On Tuesday 04 November 2003 01:02 am, Delaney, Timothy C (Timothy) wrote: > > From: Alex Martelli [mailto:aleaxit at yahoo.com] > > > > BTW, when we do come around to PEP 318, I would suggest the 'as' > > clause on a class statement as the best way to specify a metaclass. > > I just realised what has been bugging me about the idea of > > def foop() as staticmethod: > > and it applies equally well to > > class Newstyle as type: > > Basically, it completely changes the semantics associated with 'as' in > Python - which are to give something a different name (technically, to > rebind the object to a different name). Yes, that's what the 'as' clause means in from and import statements, of course. > OTOH, the first case above means 'create this (function) object, call this > decorator, and bind the name to the new object'. So instead of taking an > existing object (with an existing name) and rebinding it to a new name, it > is creating an object, doing something to it and binding it to a name. A > definite deviation from the current 'as' semantics, but understandable. I'm not sure I follow. "import X as y" means basically y = __import__('X') (give or take a little:-). 'def foo() as staticmethod:' would mean instead foo = staticmethod(new.function(<codeobj>, globals(), 'foo')) so what comes after the 'as' is a name to bind in the existing case, it's a callable to call in the new proposed syntax. There is a binding in each case, and in each case something is called to obtain the object to bind; I think the distinction between new and existing object is spurious -- __import__ can perfectly well be creating a new object -- but the real distinction is that the name to bind is given after 'as' in the existing case, it's NOT so given in the new proposed one. > However, the second case above is doing something completely different. It Not at all -- it does: Newstyle = type('Newstyle', (), <classdict>) where <classdict> is built from the body of the 'class' statement, just like, above, <codeobj> is built from the body of the 'def' statement. I find this rather close to the 'as staticmethod' case: that one calls staticmethod (the callable after the 'as') and binds the result to the name before the 'as', this one calls type (the callable after the 'as') and binds the result to the name before the 'as'. > is creating a new object (a class) and binding it to a name. As a side > effect, it is changing the metaclass of the object. The 'as' in this case "changing"? From what? It's _establishing_ the type of the name it's binding, just as (e.g.) staticmethod(...) is. I.e., stripping the syntax we have in today's Python: >>> xx = type('xx', (), {'ba':23}) >>> type(xx) <type 'type'> >>> xx = staticmethod(lambda ba: 23) >>> type(xx) <type 'staticmethod'> ...so where's the "completely different" or the "changing" in one case and not the other...? > has nothing whatsoever to do with binding the object name, but a name in > the object's namespace. It has everything to do with determining the type of the object, just like e.g. staticmethod would. > I suppose you could make the argument that the metaclass has to act as a > decorator (like in the function def above) and set the __metaclass__ > attribute, but that would mean that existing metaclasses couldn't work. It > would also mean you were defining the semantics at an implementation level. I'm sure I've lost you completely here, sorry. >>> class xx(object): pass ... >>> xx.__metaclass__ Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: type object 'xx' has no attribute '__metaclass__' why would a class created this way have to set '__metaclass__', again? A metaclass is the class object's type, and it's called to create the class object. If I do "xx = type('xx', (), {})" I get exactly the same result as with the above "class xx" statement -- no more, no less. "class" just gives me neat syntax to determine the 3 arguments with which the metaclass is called -- a string that's the classname, a tuple of bases, and a dictionary. That "__metaclass__ attribute" is just an optional hack which Python can decide to determine _which_ metaclass to call (in alternative to others, even today) for a certain 'class' statement. > I'm worried that I'm being too picky here, because I *like* the way the > above reads. I'm just worried about overloading 'as' with too many > essentially unrelated meanings. I accept that in both 'def foo() as X' and 'class foo as X' the X in "as X" is very different from its role in 'import foo as X' -- in the import statement, X is just a name to which to bind an object, while in the def and class statements X would be a callable to call in order to get the object -- and the name to bind would be the one right after the def or class keywords instead. So maybe we should do as Phillip Eby suggests and use 'is' instead - that's slightly stretched too, because after "def foo() is staticmethod:" it would NOT be the case that 'foo is staticmethod' holds, but, rather, that isinstance(foo, staticmethod) [so we're saying "IS-A", not really "IS"]. But the def and class statements cases are SO close -- in both what comes after the 'is' (or 'as') is a callable anyway. The debate is then just, should said callable be called with an already prepared (function or class) object, just to decorate it; or should it rather be called with the elementary "bricks" needed to build the object, so it can build it properly. Incidentally, it seems to me that it might not be a problem to overload e.g. staticmethod so it can be called with multiple arguments (same as new.function) and internally calls new.function itself, should there be any need for that (not that I can see any use case right now, just musing...). 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