When you decorate a method, it is not bound yet to the class, and therefor doesn’t have the im_class attribute yet. I looking for a way to get the information about the class inside the decorator. I tried this:
import types
def decorator(method):
def set_signal(self, name, value):
print name
if name == 'im_class':
print "I got the class"
method.__setattr__ = types.MethodType(set_signal, method)
return method
class Test(object):
@decorator
def bar(self, foo):
print foo
But it doesn’t print anything.
I can imagine doing this:
class Test(object):
@decorator(klass=Test)
def bar(self, foo):
print foo
But if I can avoid it, it would make my day.
__setattr__is only called on explicitobject.attribute =assignments; building a class does not use attribute assignment but builds a dictionary (Test.__dict__) instead.To access the class you have a few different options though:
Use a class decorator instead; it’ll be passed the completed class after building it, you could decorate individual methods on that class by replacing them (decorated) in the class. You could use a combination of a function decorator and a class decorator to mark which methods are to be decorated:
You could use a metaclass instead of a class decorator to achieve the same, of course.
Cheat, and use
sys._getframe()to retrieve the class from the calling frame:Note that all you can retrieve is the name of the class; the class itself is still being built at this time. You can add items to
callingframe.f_locals(a mapping) and they’ll be made part of the new class object.Access
selfwhenever the method is called.selfis a reference to the instance after all, andself.__class__is going to be, at the very least, a sub-class of the original class the function was defined in.