这不起作用:
def register_method(name=None):
def decorator(method):
# The next line assumes the decorated method is bound (which of course it isn't at this point)
cls = method.im_class
cls.my_attr = 'FOO BAR'
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
return decorator
Run Code Online (Sandbox Code Playgroud)
装饰者就像电影Inception; 你去的级别越多,它们就越混乱.我正在尝试访问定义方法的类(在定义时),以便我可以设置类的属性(或更改属性).
版本2也不起作用:
def register_method(name=None):
def decorator(method):
# The next line assumes the decorated method is bound (of course it isn't bound at this point).
cls = method.__class__ # I don't really understand this.
cls.my_attr = 'FOO BAR'
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
return decorator
Run Code Online (Sandbox Code Playgroud)
当我已经知道为什么它被破坏时,把我破碎的代码放在上面的重点是它传达了我正在尝试做的事情.
我不认为你可以用装饰器做你想做的事情(快速编辑:使用方法的装饰者,无论如何).构造方法时会调用装饰器,这是在构造类之前.您的代码不起作用的原因是因为调用装饰器时类不存在.
jldupont的评论是要走的路:如果你想设置类的属性,你应该装饰类或使用元类.
编辑:好的,看过你的评论后,我可以想到一个可能适合你的两部分解决方案.使用该方法的装饰来设置的属性的方法,然后用一元类搜索与该属性的方法和设置的相应属性类:
def TaggingDecorator(method):
"Decorate the method with an attribute to let the metaclass know it's there."
method.my_attr = 'FOO BAR'
return method # No need for a wrapper, we haven't changed
# what method actually does; your mileage may vary
class TaggingMetaclass(type):
"Metaclass to check for tags from TaggingDecorator and add them to the class."
def __new__(cls, name, bases, dct):
# Check for tagged members
has_tag = False
for member in dct.itervalues():
if hasattr(member, 'my_attr'):
has_tag = True
break
if has_tag:
# Set the class attribute
dct['my_attr'] = 'FOO BAR'
# Now let 'type' actually allocate the class object and go on with life
return type.__new__(cls, name, bases, dct)
Run Code Online (Sandbox Code Playgroud)
而已.使用方法如下:
class Foo(object):
__metaclass__ = TaggingMetaclass
pass
class Baz(Foo):
"It's enough for a base class to have the right metaclass"
@TaggingDecorator
def Bar(self):
pass
>> Baz.my_attr
'FOO BAR'
Run Code Online (Sandbox Code Playgroud)
老实说,但是?使用这种supported_methods = [...]方法.元类很酷,但是那些必须在你之后维护代码的人可能会讨厌你.