【问题标题】:Using decorator in a class in python在 python 的类中使用装饰器
【发布时间】:2020-07-22 15:58:33
【问题描述】:

为了理解 Python 中的装饰器,我在一个类中创建了一个示例。但是当我运行它时,我收到一个错误。

class Operation:

    def __init__(self, groupe):
        self.__groupe = groupe

    @property
    def groupe(self):
        return self.__groupe

    @groupe.setter
    def groupe(self, value):
        self.__groupe = value

    def addition(self, func_goodbye):
        ln_house = len('house')
        ln_school = len('school')
        add = ln_house + ln_school
        print('The result is :' + str(add))
        return func_goodbye

    @addition
    def goodbye(self):
        print('Goodbye people !!')


if __name__ == '__main__':
    p1 = Operation('Student')
    p1.goodbye()

我收到此错误:

Traceback(最近一次通话最后一次): 文件“Operation.py”,第 1 行,在 类操作: 文件“Operation.py”,第 21 行,在操作中 @添加 类型错误:addition() 缺少 1 个必需的位置参数:'func_goodbye'

【问题讨论】:

  • addition(self, func_goodbye) 需要参数 func_goodbye,这个参数没有给出。
  • 另外,你为什么要直接调用你的装饰器方法呢?你不应该打电话给goodbye吗?
  • 旁注:以这种方式使用属性在 Python 中是一种不好的做法。属性用于在不破坏属性访问的情况下实现功能。作为微不足道的“getters”和“settters”,他们没有任何好处。同样,这里没有理由使用双下划线名称。双下划线名称用于继承的名称修改,not for hiding attributes
  • 顺便说一句,您的groupe 属性完全没有意义,并违背了property 的全部目的。只需删除它们并使用普通的groupe 属性即可。
  • 在我看来,我们不能在课堂上拥有自己的装饰器!!!是真的吗?

标签: python python-3.x


【解决方案1】:

你可以有一个类作用域的装饰器,但是当装饰器被调用时不会有self

装饰者:

@foo
def bar(): ...

大致相当于

def bar(): ...
bar = foo(bar)

在您的特定示例中,如果您删除 self 参数,它应该可以按预期运行:

    def addition(func_goodbye):
        ln_house = len('house')
        ln_school = len('school')
        add = ln_house + ln_school
        print('The result is :' + str(add))
        return func_goodbye

    @addition
    def goodbye(self):
        print('Goodbye people !!')

为了更好的衡量标准,我可能会在此之后 del addition 以确保以后不会意外调用它

(旁白:一个不幸的副作用是许多 linters 和类型检查器会认为这是“奇怪的”,所以我还没有找到一种方法来安抚它们(例如 mypy))

【讨论】:

  • 安抚他们的方法是不要将不应该存在的东西放在类范围内。你也可以使用 @staticmethod 装饰器,但实际上,这个装饰器应该只是在模块级范围内。不过,赞成。
  • @juanpa.arrivillaga 你有什么可以支持你的观点的吗? (例如)从设计的角度来看,拥有一个了解类内部的私有装饰器可能是有意义的——当你尝试修改这些内部和(至少对我而言)一个装饰器时,你会遇到一个等效的 linter 问题在这种情况下,在类主体中定义很有意义
  • 在这种情况下可能是@classmethod,但是,在这种情况下,函数明确地不使用任何内部状态,因此它不应该是类的一部分。
  • @juanpa.arrivillaga 很容易,这里是an example
  • @classmethod 对此没有帮助,您想要运行装饰器时没有类(NameError: <classname> is not defined),并且@staticmethod 也不起作用,因为它会生成描述符(staticmethod is not callable)
猜你喜欢
  • 2021-07-16
  • 2011-11-20
  • 1970-01-01
  • 2019-09-20
  • 2010-10-14
  • 1970-01-01
  • 2011-04-28
  • 2017-02-17
相关资源
最近更新 更多