Python - decorator - trying to access the parent class of a method -
this doesn't work:
def register_method(name=none): def decorator(method): # next line assumes decorated method bound (which of course isn't @ point) cls = method.im_class cls.my_attr = 'foo bar' def wrapper(*args, **kwargs): method(*args, **kwargs) return wrapper return decorator
decorators movie inception; more levels in go, more confusing are. i'm trying access class defines method (at definition time) can set attribute (or alter attribute) of class.
version 2 doesn't work:
def register_method(name=none): def decorator(method): # next line assumes decorated method bound (of course isn't bound @ point). cls = method.__class__ # don't understand this. cls.my_attr = 'foo bar' def wrapper(*args, **kwargs): method(*args, **kwargs) return wrapper return decorator
the point of putting broken code above when know why it's broken conveys i'm trying do.
i don't think can want decorator (quick edit: decorator of method, anyway). decorator gets called when method gets constructed, before class constructed. reason code isn't working because class doesn't exist when decorator called.
jldupont's comment way go: if want set attribute of class, should either decorate class or use metaclass.
edit: okay, having seen comment, can think of two-part solution might work you. use decorator of method set attribute of method, , use metaclass search methods attribute , set appropriate attribute of class:
def taggingdecorator(method): "decorate method attribute let metaclass know it's there." method.my_attr = 'foo bar' return method # no need wrapper, haven't changed # method does; mileage may vary class taggingmetaclass(type): "metaclass check tags taggingdecorator , add them class." def __new__(cls, name, bases, dct): # check tagged members has_tag = false member in dct.itervalues(): if hasattr(member, 'my_attr'): has_tag = true break if has_tag: # set class attribute dct['my_attr'] = 'foo bar' # let 'type' allocate class object , go on life return type.__new__(cls, name, bases, dct)
that's it. use follows:
class foo(object): __metaclass__ = taggingmetaclass pass class baz(foo): "it's enough base class have right metaclass" @taggingdecorator def bar(self): pass >> baz.my_attr 'foo bar'
honestly, though? use supported_methods = [...]
approach. metaclasses cool, people have maintain code after hate you.
Comments
Post a Comment