本文介绍了Python-装饰器-尝试访问方法的父类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 这不起作用: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装饰就像电影《盗梦空间》一样;您进入的级别越多,它们就越混乱。我正在尝试访问定义方法的类(在定义时),以便可以设置类的属性(或更改属性)。Decorators are like the movie Inception; the more levels in you go, the more confusing they are. I'm trying to access the class that defines a method (at definition time) so that I can set an attribute (or alter an attribute) of the class.版本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当我已经知道为什么破坏代码时,将破坏代码放在上面的要点是它传达了我想做的事情。The point of putting my broken code above when I already know why it's broken is that it conveys what I'm trying to do.推荐答案我不认为您可以用装饰器做您想做的事情(快速编辑:无论如何都使用该方法的修饰符)。当构造方法时,即在构造类之前 ,装饰器将被调用。您的代码无法正常运行的原因是因为调用装饰器时该类不存在。I don't think you can do what you want to do with a decorator (quick edit: with a decorator of the method, anyway). The decorator gets called when the method gets constructed, which is before the class is constructed. The reason your code isn't working is because the class doesn't exist when the decorator is called. jldupont的注释是处理方法:如果要设置 class 的一个属性,您应该修饰该类或使用一个元类。jldupont's comment is the way to go: if you want to set an attribute of the class, you should either decorate the class or use a metaclass.编辑:好的,看完您的评论后,我可以考虑一个两部分的解决方案可能对您有用。使用该方法的修饰符设置方法的属性,然后使用元类搜索具有该属性的方法,并设置 class 的适当属性: okay, having seen your comment, I can think of a two-part solution that might work for you. Use a decorator of the method to set an attribute of the method, and then use a metaclass to search for methods with that attribute and set the appropriate attribute of the class: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 varyclass 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)就是这样。用法如下:class Foo(object): __metaclass__ = TaggingMetaclass passclass Baz(Foo): "It's enough for a base class to have the right metaclass" @TaggingDecorator def Bar(self): pass>> Baz.my_attr'FOO BAR'不过,诚实吗?使用 supported_methods = [...] 方法。元类很酷,但是在您之后必须维护您的代码的人可能会讨厌您。Honestly, though? Use the supported_methods = [...] approach. Metaclasses are cool, but people who have to maintain your code after you will probably hate you. 这篇关于Python-装饰器-尝试访问方法的父类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-20 14:22