【问题标题】:How can I define decorator method inside class? [duplicate]如何在类中定义装饰器方法? [复制]
【发布时间】:2012-12-13 02:46:12
【问题描述】:

这是一个例子。

class myclass:
    def __init__(self):
        self.start = False
        
    def check(self):
        return not self.start
    
    def doA(self):
        if self.check():
            return
        print('A')
        
    def doB(self):
        if self.check():
            return
        print('B')

如您所见,我想用装饰器的方式编写检查动作,但经过多次尝试,我发现我只能在我的类之外编写方法。请教我如何在课堂上写。

我可以这样写代码:

def check(func):
    def checked(self):
        if not self.start:
            return
        func(self)
    return checked

class myclass:
    def __init__(self):
        self.start = False
        
    @check
    def doA(self):
        print('A')
        
    @check
    def doB(self):
        print('B')
        

a = myclass()

a.doA()
a.doB()

a.start = True

a.doA()
a.doB()

但我认为这不是一个好习惯,我想在我的类中定义检查方法。

【问题讨论】:

  • 我不清楚你在问什么。你能改写一下,或者提供一个例子吗?
  • 你的问题还不清楚。您的第一个代码示例不包括任何装饰器的使用。你想用什么作为装饰器,如果它不起作用,会发生什么?你有错误吗?如果是这样,什么错误?显示产生该错误的实际代码。
  • 所以你想在一个(或多个)成员方法的类中使用装饰器?如果是这样,我明白你想要什么,我不明白你为什么想要它?这没有令人信服的理由。 class 是一个整洁的容器,你不需要装饰器作为类的方法,你可以从另一个方法调用一个方法。这是不是被decorators 冲昏了头脑?

标签: python


【解决方案1】:

虽然我认为这并不是一直都完全需要的,但这里是您在课堂上制作装饰器的方法。由于稍后方法绑定到self 的方式,这有点麻烦。通常使用普通函数装饰器,您不必担心这一点。

要求是:

  1. 需要在使用它的方法之前先定义装饰器
  2. 需要使用functools.wraps才能正确保留绑定的方法

例子:

from functools import wraps

class myclass:
    def __init__(self):
        self.start = False

    def _with_check(f):
        @wraps(f)
        def wrapped(inst, *args, **kwargs):
            if inst.check():
                return
            return f(inst, *args, **kwargs)
        return wrapped

    def check(self):
        return self.start

    @_with_check
    def doA(self):
        print('A')

    @_with_check
    def doB(self):
        print('B')

我将它设置为受保护成员,因为它实际上并不是其他人需要在课堂之外使用的东西。它仍然保留您的公共check() 呼叫以供自己使用。装饰器只是在调用目标方法之前先调用它。

【讨论】:

  • 如果我在类中定义了一个没有self作为第一个参数的方法,pydev会出错,方法'check-test'应该有self作为第一个参数,但它可以正常运行,我被骗了.
  • @Max @jdi 为什么不用@staticmethod 来装饰装饰器呢?我知道它看起来很夸张,但这会解决它。
  • @J.C.Rocamonde 然后会报错“TypeError: 'staticmethod' object is not callable”
  • @Tim 不,我已经在之前的评论中回答了这个问题。装饰器在类将其转换为绑定方法之前应用于方法。
  • @DonLarry 谢谢!固定
【解决方案2】:

如果您需要修改一个类上调用了多少或所有方法,但您只想将该行为更改应用到该类及其子类,只需使用__getattr__() 和/或__getattribute__() 即可而是执行你的行为。

【讨论】:

    猜你喜欢
    • 2021-11-10
    • 2012-02-09
    • 2014-01-14
    • 2019-02-03
    相关资源
    最近更新 更多