python: static methods and the class decorator
May 2nd, 2010
No comments
When one uses a class decorator python wraps the class definition like this:
class RegisterExposedMethods (object): def __init__(self, decoratedClass, registry): self._decoratedClass = decoratedClass def __call__(self,*__args,**__kw): return self._decoratedClass(*__args,**__kw) @RegisterExposedMethods class MyClass (object): def __init__(self): object.__init__(self) @staticfunction def stat (blah): print "blah: %s" % blah A = RegisterExposedMethods (MyClass)
If you write the class decorator like I did, this has 2 major problems in it:
1.) static function stat will not be accessible
2.) in stack traces the class MyClass is named like the decorator function RegisterExposedMethods
You can see both problems in this stack trace:
<function coolFunction at 0x018C9630> Traceback (most recent call last): File "class_decorator.py", line 37, in <module> MyClass.stat() AttributeError: 'RegisterExposedMethods' object has no attribute 'stat'
To solve the two issues I’ve added the following to my decorator:
class RegisterExposedMethods (object): def __init__(self, decoratedClass): self._decoratedClass = decoratedClass # cloak us as the original class (problem 2.) self.__class__.__name__ = decoratedClass.__name__ def __call__(self,*__args,**__kw): print "RegisterExposedMethods.call" return self._decoratedClass(*__args,**__kw) # define a getattr function to get the static function from the decorated class def __getattr__(self, name): return getattr(self._decoratedClass, name)
The problem with 1.) is that the class definition is wrapped. With that in place the static method is searched firstly on the decorator class
and not on the decorated class.