[Python-Dev] Use case for class decorators
Goncalo Rodrigues
op73418 at mail.telepac.pt
Thu Apr 15 15:22:00 EDT 2004
Here is a use case for class decorators.
I find myself writing a lot of proxies and adapters. Usually, they are just a
subclass of something as simple as
class Proxy(object):
"""The Proxy base class."""
def __init__(self, obj):
"""The initializer."""
super(Proxy, self).__init__(obj)
#Private attributes.
self.__obj = obj
#Read-only properties.
__obj__ = property(lambda self: self.__obj,
doc = "The underlying object of the Proxy.")
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__,
self.__obj__)
def __getattr__(self, attrib):
return getattr(self.__obj__, attrib)
This is all fine and dandy, except that no magic methods are trapped. Usually,
I just inject them directly after the class statement via:
#Auxiliary getter function.
def getter(attrib):
return lambda self, *args, **kwargs: getattr(self.__obj__, attrib)(*args,
**kwargs)
def inject(cls, magicnames):
"""Inject magic methods directly in a class.
Warning(s):
- Only magic names are injected.
- Does not overwrite already present magic names.
"""
for magicname in magicnames:
if magicname.startswith("__") and magicname.endswith("__"):
if not hasattr(cls, magicname):
setattr(cls, magicname, getter(magicname))
The function inject is a use case for a class decorator. If it's a good use
case that's something I'll leave you to argue at will (<runs away>). I think
it's fairly obvious that using a metaclass to do this simple operation is a
clear case of the wrong tool for the job.
With my best regards,
G. Rodrigues
p.s:
<comment on syntax>
The syntax for decorators:
[dec1, dec2, ...]
def foo(arg1, arg2, ...):
pass
is probably the worst of all syntaxes (with appologies for my bluntness). It
just doesn't parse well. What I see in the above proposed syntax is just a list
literal and a definition statement. There's no indication that the two are
somehow linked (I can't express this any better, English is not my native
lingo).
The best, IMHO is
def foo(arg1, arg2, ...) [dec1, dec2, ...]:
pass
<\ comment on syntax>
More information about the Python-Dev
mailing list