At 09:24 AM 11/4/03 +0100, Alex Martelli wrote: >On Tuesday 04 November 2003 02:09 am, Phillip J. Eby wrote: > ... > > I'm not all that enthused about the metaclass usage, mainly because there's > > already an okay syntax (__metaclass__) for it. I'd rather that class > >Hmmm -- why is: > >class Foo: > __metaclass__ = MetaFoo > ... > >"ok", compared to e.g.: > >class Foo is MetaFoo: > ... > >while, again for example, > > def foo(): > ... > foo = staticmethod(foo) > >is presumably deemed "not ok" compared to e.g.: > > def foo() is staticmethod: > ... > >??? Isn't it obvious from the above? Note the positioning of the '...' in all but the third example you've shown. :) > > decorators (if added) were decorators in the same way as function > > decorators. Why? Because I think that correct, combinable class > > decorators are probably easier for most people to write than correct, > > combinable metaclasses, and they are more easily combined than metaclasses > > are. > >Combinable metaclasses may not be trivial to write, but with multiple >inheritance it will often be feasible (except, presumably, when implied >layout or __new__ have conflicting requirements). I guess my point is that it's harder to *learn* how to write a co-operative metaclass, than it is to simply *write* a co-operative decorator. A metaclass must explicitly invoke its collaborators, but a decorator is just a simple function; the chaining is external. Now, certainly you and I both know how to write our metaclasses co-operatively, but I believe both of us have also been told (repeatedly) that we're not typical Python programmers. :) > Of course, not having use >cases of either custom metaclasses or class decorators in production use, the >iscussion does risk being a bit abstract. Did you have any specific use case >in mind? PyProtocols has an API call that "wants" to be a class decorator, to declare interface information about the class, e.g: class MyClass is protocols.instancesProvide(IFoo): .... But, since there are no such things as class decorators, it actually uses a sys._getframe() hack to replace the metaclass and simulate decoratorness. Steve Alexander originally proposed the idea as an implementation technique for interface declarations in Zope 3, and I worked up the actual implementation, that's now shared by PyProtocols and Zope 3. So the above is actually rendered now as: class MyClass: protocols.advise(instancesProvide=[IFoo]) (Note that any explicit __metaclass__ declaration has to come *before* the advise() call.) The principal limitation of this technique is that writing co-operative decorators of this sort is just as difficult as writing co-operative metaclasses. So, PyProtocols and Zope 3 include a library function, 'addClassAdvisor(decorator_callable)' which adds a decorator function (in a PEP 218-style execution order) to those that will be called on the resulting class. IOW, we created a decorator mechanism for classes that is almost identical to the PEP 218 mechanism for functions, to make it easy to call functions on a created class, using declarations that occur near the class statement. This was specifically to make it easier to do simple decorator-like things, without writing metaclasses, and thus not interfering with user-supplied metaclasses. Note, by the way, that since you can only have one explicit metaclass, and Python does not automatically generate new metaclasses, users must explicitly mix metaclasses in order to use them. That's all well and good for gurus such as ourselves, but if you're creating a framework that wants to play nicely with other frameworks, and is for non-guru users, then metaclasses are right out unless they're the *only* way to achieve the desired effect. For supplying framework metadata, decorators are an adequate mechanism that's simpler to implement, and are therefore preferable. Since the 'addClassAdvisor()' mechanism has been available, I've used it for other framework metadata annotations, such as security restrictions, and to perform miscellaneous other "postprocessing" operations on classes. Now, in the time since Steve Alexander first proposed the idea, I've actually grown to like the in-body declaration style for classes, and it's possible that PEP 218-style declaration for classes would be more unwieldy. So I'm only +0 on having a class decorator syntax at all. But I do think that if there *is* a class decorator syntax, its semantics should exactly match function decorator syntax, and am therefore -1 on it being metaclass syntax. In my experience, non-guru usage of metaclasses is usually by inheriting the metaclass from a framework base class, and this is the "right way to do it" because the user shouldn't need to know about metaclasses unless they are mixing them. (And if Python mixed them for you, there'd be no need for non-gurus to know about metaclasses at all.)
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