Reputation: 20805
I have been using the following (Jython 2.7) code to decorate functions in some classes:
import sys
import inspect
from decorator import decorator
def useless_decorator(method, *args, **kwargs):
#Does nothing yet :D
return method(*args, **kwargs)
class UselessMetaClass(type):
def __new__(cls, clsname, bases, dict):
for name, method in dict.items():
if not name.startswith('_') and inspect.isroutine(method):
dict[name] = decorator(useless_decorator, method)
return type.__new__(cls, clsname, bases, dict)
class Useless(object):
__metaclass__ = UselessMetaClass
The goal is to decorate all public functions (i.e. ones with names that don't start with an underscore) with the useless_decorator
. Of course, this behaviour is only expected in classes that inherit from Useless
.
Unfortunately I've been running into metaclass conflict errors. I've had great difficulty debugging them and I think they're occurring for reasons beyond my control (due to a third party library I'm using: Sikuli).
But, maybe I don't need to use a metaclass at all! Does anyone know a way to simulate my above code without using a metaclass?
I.E., Is there any other way to apply a decorator to all functions in a class?
(P.S. I know I could manually decorate each function, but that's not the solution I'm looking for)
Upvotes: 2
Views: 727
Reputation: 69052
Converting your metaclass to a class decorator should be straight forward. A class decorator simly receives the class as argument and returns the (modified) class:
def useless_class_decorator(cls):
for name, method in cls.__dict__.items():
if not name.startswith('_') and inspect.isroutine(method):
setattr(cls, name, decorator(useless_decorator, method))
return cls
The main difference here is that you can't direcly change cls.__dict__
here, as for new style classes that will be a dictproxy which does not support assignment, so you have to use setattr
on the class instead. Then you simply create your class:
@useless_class_decorator
class Useless(object):
def method_to_decorate(self, *args, *kwargs):
...
However this won't affect subclasses of Useless
, those would also have to be decorated using the class decorator. If that's not acceptable, then a metaclass may be the better option...
Upvotes: 4