python - 在函数装饰器中调用 Python 实例方法

标签 python methods decorator instance

是否有一种简洁的方法让装饰器仅在实例化类的实例时调用类的实例方法?

class C:
    def instance_method(self):
      print('Method called')

    def decorator(f):
        print('Locals in decorator %s  ' % locals())
        def wrap(f):
            print('Locals in wrapper   %s' % locals())
            self.instance_method()
            return f
        return wrap

    @decorator
    def function(self):
      pass

c = C()
c.function()

我知道这不起作用,因为 self 在调用 decorator 时未定义(因为它没有作为实例方法调用,因为没有可用的引用类)。然后我想出了这个解决方案:

class C:
    def instance_method(self):
      print('Method called')

    def decorator():
        print('Locals in decorator %s  ' % locals())
        def wrap(f):
            def wrapped_f(*args):
                print('Locals in wrapper   %s' % locals())
                args[0].instance_method()
                return f
            return wrapped_f
        return wrap

    @decorator()
    def function(self):
      pass

c = C()
c.function()

这利用了这样一个事实,即我知道任何实例方法的第一个参数都是 self。这个包装器定义方式的问题是每次执行函数时都会调用实例方法,这是我不希望的。然后我想出了以下有效的轻微修改:

class C:
    def instance_method(self):
      print('Method called')
def decorator(called=[]):
    print('Locals in decorator %s  ' % locals())
    def wrap(f):
        def wrapped_f(*args):
            print('Locals in wrapper   %s' % locals())
            if f.__name__ not in called:
                called.append(f.__name__)
                args[0].instance_method()
            return f
        return wrapped_f
    return wrap

@decorator()
def function(self):
  pass

c = C()
c.function()
c.function()

现在该函数只被调用一次,但我不喜欢每次调用该函数时都必须进行此检查的事实。我猜没有办法解决它,但如果有人有任何建议,我很想听听他们的意见!谢谢:)

最佳答案

我想出了一个可能的替代解决方案。我喜欢它,因为在定义函数时只发生一次调用,在类实例化时发生一次。唯一的缺点是函数属性会消耗一点点额外的内存。

from types import FunctionType

class C:
    def __init__(self):
        for name,f in C.__dict__.iteritems():
            if type(f) == FunctionType and hasattr(f, 'setup'):
                  self.instance_method()

    def instance_method(self):
      print('Method called')

    def decorator(f):
        setattr(f, 'setup', True)
        return f

    @decorator
    def function(self):
      pass

c = C()
c.function()
c.function()

关于python - 在函数装饰器中调用 Python 实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3371680/

相关文章:

c# - 从类中调用方法

将方法作为回调传递的 javascript 问题

c# - 扩展方法 - 装饰者模式

python - 递归二叉搜索树插入

PyQt4 的 Python 导入失败

python - 如何抓取 YouTube channel 创建者并链接到他们的 channel ?

python - Python 中的 PCI 总线接口(interface)

javascript - 是否可以读取 JavaScript 全局/内置对象方法(即 array.filter、.sort)的代码?

python - 解释这个高阶函数行为

python - Python 中的单元测试装饰器