"Rainer Deyke" <root at rainerdeyke.com> wrote in message news:vQpD6.47756$J%5.15806884 at news2.rdc2.tx.home.com... [snip] > "Alex Martelli" <aleaxit at yahoo.com> wrote in message > news:9bkvi30uf8 at news1.newsguy.com... > > "Rainer Deyke" <root at rainerdeyke.com> wrote in message > > news:OLlD6.46125$J%5.15304817 at news2.rdc2.tx.home.com... > > How do you stop a class from having subclasses in Python? > > def f(): > class C: > pass > C() Ok, it's now clearer what you mean, thanks. It doesn't STOP somebody sufficiently determined from subclassing it, of course: class OhYeah(f().__class__): pass but it does provide a rather good hint that "being subclassed" is not the class's design intention:-). > This is, incidentially, the idiom I had to use extensively to deal with the > lack of nested scoping in Python. More generally, you write a class for How does a local class help you there in ways nested scoping will make obsolete? Sounds interesting. > > what is the supposed benefit of that -- assuming you can find any > > benefits for the singleton DP anywhere, of course). > > The benefit of enforcing lack of inheritance? There is none, unless you > believe in the C++/Java way of preventing abuse through access restrictions. Java does enforce that, but in Python you get no "abuse protection" (and no access restrictions) unless via restricted execution, bastions &c (and C++, notoriously, only "makes believe" any security accrues -- actually the language standard makes it pretty clear that no abuse is really prevented, but few practitioners seem to get it). > The benefit of singletons? Consider the following module: > > # spam.py > def set_variable(name, value): > do_something() > > def get_variable(name): > return do_something_else() > > def del_variable(name): > do_something_completely_different() > > To facilitate easier access to these functions, I introduce the following > wrapper: > > class VariableAccess: > def __setattr__(self, name, value): > set_variable(name, value) > def __getattr__(self, name): > return get_variable(name) > def __delattr__(self, name): > return del_variable(name) > variables = VariableAccess() > > > Now the client can access the revealed variables through a more natural > interface. Nice -- a specifically Pythonic benefit. Of course, it's no problem if VariableAccess gets multiply instantiated, so I would consider this an example of the pattern "Featherweight" (a class whose instances share all state) rather than one of the pattern "Singleton" (a class that is protected against being multiply instantiated), and I like FW as much as I dislike Singleton, so there's still no benefit to the singleton design pattern, but that's another issue. > Consider the following hypothetical Python-like language: > > def f(): > print 'spam' > > class C: > def f(): # Note lack of 'self' > print 'eggs' > def g(): > __instance__.f() > __module__.f() > > I'm not sure I like this myself (the __magic__ names are too long, the > result of a 'def' statement depends on context, there's no clear way to > refer to the outer class from a method in an inner class, magically > appearing variables have the potential to cause trouble, and the > 'C.f(instance_of_C)' conventions seems to be broken), but at least it's > better than the strawman against which you seem to have been arguing. Actually, I think _this_ is "a strawman proposal" -- one with some admitted defects but that at some level realizes design intentions. Earlier, I saw complaints but no pointer to resolving them. Thanks for posting it at last. I fully agree with all of your criticisms, and furthermore don't see how this will support the useful idiom of assigning an existing function to serve as a method, but then, pointing out such issues _IS_ a strawman proposal's role. I do see one nugget here -- allowing access to a module object through one of its own magic attributes may indeed be handier than using globals(), sys.modules[__name__], and other existing idioms. The 'reference loop' it implies may be less terrible today (what with weak references, garbage collection, etc) than it may once have appeared. Having each module object possess a __module__ attribute that references the object itself seems feasible, if the need to use that object is indeed frequent. A somewhat related issue is somehow getting easy access to the function object from that function's code -- particularly likely to be interesting now that function objects have arbitrary attributes. Presumably harder as the __function__ (or whatever) would have to be stuck in (the locals...?). Just an aside, anyway. > I'm saying specifically that C++ is right in providing a way to qualify > names as global - no more. OK, I accept that's what you intended to say right from the start. Now, "global" in C++ means "global across all sources" rather than "specific to this source". Object specific to this module would be in the unnamed namespace (since the use of 'static' for that is [informally speaking only, I believe] deprecated in C++) and thus non-qualifiable; other (non-unnamed) namespaces are shared across sources. Are you expressing admiration for THIS trait of C++? Or do you actually wish to keep things Pythonically simple and is the C++ reference some sort of red herring? It's starting to look that way to me. > def factorial(n): > if n <= 1: > return 1 > else: > return globals()['factorial'](n - 1) > > Do you actually write like that, or do you mean "I am too lazy to explitly > qualify global names, explicit-better-than-implicit be damned, so 'globals' > is good enough for me"? I don't write like that, although my lack of qualification for (module) globals stems from desire for simplicity and clarity, rather than from laziness. I do use globals() in those rare instances where I feel I need it -- only one that comes to mind readily is a function which is documented to have a parameter named 'feep' (can't change that without breaking client code) living in a module that is also documented to have an attribute named 'feep' (ditto); then, from within that function, accessing globals() is one possibility if the global 'feep' is needed (there are others, of course, such as a module-level _feep = feep to provide handier internal access). You _have_ convinced me that, if every module had a magic attribute __module__ returning itself, some cases of such explicit-to-global access would be facilitated wrt the present situation. And, although such need is rare in my code, I have no basis for asserting that it would be also rare in others' -- e.g., maybe somebody _IS_ designing libraries where module-level attributes and function optional arguments systematically share names, and has data to show that this makes his clients' life easier. > > What would the "over-specialized syntax" you are attacking be > > in this case? Please be specific. > > In this case, the 'global' statement. I think I see -- if we had __module__, then the global statement might eventually be deprecated in favor of suggesting the idiom __module__.feep = 23 to rebind globals, rather than the present global feep feep = 23 An interesting possibility, and one worth thinking about (I'm not sure I like it, but I'm also far from sure I dislike it). Discussion would have been shorter if you had indicated this a TAD more explicitly from the start rather than "deprecating self", lauding C++, etc, but I guess that's just another explicit/implicit thing:-). It _does_ look "more pythonic" than 'global', in a sense. Why don't you do a PEP on this? It seems definitely worthwhile to discuss, and I don't think it will get the attention it deserves when buried at the end of a long post in a subthread of a long thread with a title not very clearly related to it (though I've tried to change subject in case this does help it get read:-). Alex
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4