Python - 装饰器 - 尝试访问方法的父类

2024-05-11

这不起作用:

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

装饰器就像电影《盗梦空间》一样;你的关卡越多,它们就越令人困惑。我正在尝试访问定义方法(在定义时)的类,以便我可以设置该类的属性(或更改属性)。

版本 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

当我已经知道代码损坏的原因时,将其放在上面的目的是它传达了我想要做的事情。


我不认为你可以用装饰器做你想做的事情(快速编辑:无论如何,使用方法的装饰器)。构造方法时会调用装饰器,即before该类已构建。您的代码不起作用的原因是调用装饰器时该类不存在。

jldupont 的评论是要走的路:如果你想设置class,您应该装饰类或使用元类。

编辑:好的,看到您的评论后,我可以想到一个可能适合您的两部分解决方案。使用方法的装饰器来设置方法的属性method,然后使用元类搜索具有该属性的方法并设置适当的属性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 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)

就是这样。使用方法如下:

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'

老实说,不过?使用supported_methods = [...]方法。元类很酷,但是在你之后必须维护你的代码的人可能会讨厌你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python - 装饰器 - 尝试访问方法的父类 的相关文章

随机推荐