【问题标题】:Python decorator in a class: missing required positional arguments:类中的 Python 装饰器:缺少必需的位置参数:
【发布时间】:2022-01-22 03:48:14
【问题描述】:
class Something:
    def __init__(self, ...):
       ...

    def update(self):
       ...

    def add_update(self, func):
      def fct(*args, **kwargs):
          self.update()
          func(*args, **kwargs)
      return fct 

    @add_update
    def method(self, some_parameter):
       ...

所以基本上我有这个类,我想在调用类中的方法之前自动调用函数“update()”。但我得到这个错误:

TypeError: add_update() missing 1 required positional argument: 'func'

我真的不明白这里出了什么问题,我也在互联网上看到了一些教程,他们做了类似的事情并且它正在工作。谁能解释一下这里出了什么问题以及如何解决?

【问题讨论】:

  • 你需要传递参数func。
  • 您没有将add_update 用作方法,而是将其用作装饰器函数,因此它没有self 参数。 self 将是 fct 的第一个参数。

标签: python python-decorators python-class


【解决方案1】:

什么是装饰器?它是更详细语法的语法糖。

@decorator
def my_fun():
   ...

相同
my_fun = decorator(my_fun)

所以在你的具体情况下

method = add_update(method)

您发现问题了吗?添加更新需要两个参数(self 和 func),但这里它只得到一个(实际上您将 method 作为 self 传递)。

要解决这个问题,你需要在只获取函数的类之外创建装饰器,并且函数的第一个参数将是 self:

def add_update(func):
     def wrapper(*args):
         self = args[0]
         ...

【讨论】:

    【解决方案2】:

    当你使用@add_update时,相当于add_update(method),此时add_update还是一个函数。

    您可以进行以下修改以使其工作

    class Something:
        def __init__(self):
            ...
    
        def update(self):
            ...
    
        def add_update(f):
            def fct(self, *args, **kwargs):
                self.update()
                return f(self, *args, **kwargs)
    
            return fct
    
        @add_update
        def method(self, some_parameter):
            ...
    
    

    【讨论】:

    • 现在当我从类中调用“方法”方法时。我收到以下错误:method() 缺少 1 个必需的位置参数:'some_parameter'
    • method是一个方法,有参数,需要给它加参数,比如Something().method(1)
    • 你可能用上面的例子代替了我的例子,这里调用的是Something.update()而不是args[0].update(),所以会报错
    • 我正在使用你的例子,我做了这样的事情: test = Something(...) test.method(some_parameter) 我得到这个错误:method() missing 1 required positional argument: 'some_parameter'
    • 我这里运行不会报错,能不能发你的代码截图
    【解决方案3】:

    您必须传递参数func 并在装饰器函数中定义类。

    class Something:
        def __init__(self,..):
            ...
          
    
        def update(self):
           ...
    
        def add_update( func):
          def fct(*args, **kwargs):
              args[0].update() #or Something.update()
              func(*args, **kwargs)
          return fct 
    
        @add_update
        def method(self, some_parameter):
            ...
    

    【讨论】:

    • 这样修改后出现此错误:update() 缺少 1 个必需的位置参数:'self'
    • 你需要这样做Something.update(),我运行它没有错误。
    • 你需要把Something.update()改成args[0].update(),如果你愿意,你甚至可以把Something.update()改成Something.update(args[0]),都是一样的
    • 两者都在工作。
    • @I_Al-thamary 谢谢,到现在才知道有这样的东西!!,可以让我们的交流更方便。
    猜你喜欢
    • 2019-11-26
    • 2019-01-24
    • 2023-04-03
    • 2019-09-07
    • 2021-02-22
    • 1970-01-01
    • 2021-07-28
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多