[Python-Dev] PEP 487 vs 422 (dynamic class decoration)
Eric Snow
ericsnowcurrently at gmail.com
Mon Apr 6 18:12:07 CEST 2015
On Fri, Apr 3, 2015 at 6:44 AM, Martin Teichmann
<lkb.teichmann at gmail.com> wrote:
> Nick, I couldn't agree more with you, yet I think PJ actually brought
> up a very interesting point. Post-processing is a very common thing
> these days, and has been re-written so many times that I think it is
> about time that something like it should be in the standard library.
Here's another approach that would help. Support a mechanism for
inheriting class decorators. Classes would have an attribute like
__subclass_decorators__ that would hold a tuple of all the inherited
decorators. They would be applied, in order, in __build_class__
before any explicit decorators are.
One way to accomplish this is with a meta-decorator, e.g.
"classutil.inherited_decorator". You would decorate a class decorator
with it:
def inherited_decorator(deco):
def new_deco(cls):
cls = deco(cls)
try:
inherited = cls.__subclass_decorators__
except AttributeError:
cls.__subclass_decorators__ = (deco,)
else:
cls.__subclass_decorators__ = inherited + (deco,)
return cls
@inherited_decorator
def register(cls):
registry.add(cls)
return cls
@register
class X:
...
The downside to the meta-decorator is that is isn't apparent when the
class decorator is used that it will be inherited. It could also be
used directly to make it more apparent:
def register(cls):
registry.add(cls)
return cls
@inherited(register)
class X:
...
However, that doesn't read well. Syntax would be better, but is a
harder sell and a little grittier:
def register(cls):
registry.add(cls)
return cls
@@register
class X:
-eric
More information about the Python-Dev
mailing list