【问题标题】:Python: Calling a decorator method from another classPython:从另一个类调用装饰器方法
【发布时间】:2015-09-18 15:30:46
【问题描述】:

假设我有一个定义装饰器的类

class Foo():

    def decorate(param):        
        def wrapper(func):
            def wrapped(*args, **kwargs):
                # do something
                return func(*args, **kwargs)
            return wrapped
        return wrapper

然后我决定在另一个类中调用该装饰器,如下所示:

class Bar():

    foo = Foo()
    param = something

    @foo.decorate(param)
    def func():
        # do something

这会引发TypeError 异常:

TypeError: decorate() takes 1 positional argument but 2 were given

我无法理解这里出了什么问题。应用相同的装饰器但在同一类中定义 Bar 可以正常工作,但为什么它不适用于不同的类?

【问题讨论】:

    标签: python class decorator


    【解决方案1】:

    你的 decorate() 函数应该是一个实例方法,因此它接受实例本身作为第一个参数,当你调用 - @foo.decorate(param) 时,你试图传递两个参数(因为 foo 是一个实例Foo 类)实例本身,以及导致问题的 param

    您应该将decorate() 方法转换为接受实例作为第一个参数。示例 -

    class Foo():
    
        def decorate(self, param):        
            def wrapper(func):
                def wrapped(*args, **kwargs):
                    # do something
                    return func(*args, **kwargs)
                return wrapped
            return wrapper
    

    另外,你的 func() 也是一个实例方法,它也需要一个 self 。示例 -

    class Bar():
    
        foo = Foo()
        param = something
    
        @foo.decorate(param)
        def func(self):
            # do something
    

    【讨论】:

      【解决方案2】:

      您只是忘记包含self;你正在调用Foo().decorate(),一个绑定的方法,所以实例会被传入:

      class Foo():
          def decorate(self, param):        
      

      请注意,这同样适用于您的 Bar.func() 函数:

      class Bar():
      
          foo = Foo()
          param = something
      
          @foo.decorate(param)
          def func(self):
              # do something
      

      【讨论】:

      • 实例化Bar 并尝试调用func 也会失败;它还需要以self为参数。
      • @chucksmash:当然,但我们可以合理地假设它是不完整的示例代码;错误消息显示,对于装饰器工厂方法,至少 self 肯定被遗忘了。
      • 它仍然不起作用,我只是添加了 self 作为装饰器的参数,但它仍然给我同样的错误。
      • @jablesauce:那么请给我们一个minimal reproducible example;一个包含您获得的异常的完整回溯。您是否确保重新启动 Python 以加载脚本的新版本?
      • 其实我的不好,没有重启Python。我不知道您必须完全重新启动解释器,而只是尝试重新解释脚本本身。
      猜你喜欢
      • 2021-12-26
      • 2016-03-17
      • 2021-10-23
      • 2017-11-16
      • 1970-01-01
      • 2011-07-03
      • 2021-04-20
      • 2018-08-15
      • 2016-03-21
      相关资源
      最近更新 更多