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

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -