python - 在类实例和类定义上调用类装饰器有什么区别?

标签 python python-decorators class-decorator

class Deco:
    def __init__(self, name):
        self.name = name
    def __call__(self, test_class):
        def inner_func(whatisit):
            return whatisit
        test_class.method = inner_func
        return test_class

class TestClass:
    def __init__(self, name):
        self.name = name
    
@Deco('deco')
class TestClassWrapped:
    def __init__(self, name):
        self.name = name

test = TestClass('test')
test = Deco('deco')(test)

test_wrapped = TestClassWrapped('test')

print(test.method('whatisit')) >> whatisist
print(test_wrapped == test_wrapped.method()) >> True

为什么 test.methodtest_wrapped.method 返回不同的结果?
似乎 test_wrapped.method 中的第一个参数是 self,而不是 test.method。为什么两者不同?

最佳答案

区别不在于装饰的工作方式,而在于调用的工作方式。当实例调用在其类上定义的方法时,如 test_wrapped确实如此,它总是通过 self作为第一个参数。同时,当一个对象调用它自己的一个属性时,它恰好是一个函数,但在它的类中不存在,它会在不传递 self 的情况下调用它。 .考虑这个简单的类:

class LoudTalker:
    def __init__(self, name):
        self.shout_hello = lambda: print("HELLO, I'M {}".format(name.upper()))

>>> john = LoudTalker("John")
>>> LoudTalker.shout_hello()
HELLO, I'M JOHN

请注意 john没有通过selfshout_hello (这会引发错误 <lambda>() takes 0 positional arguments but 1 was given )因为 shout_hello直接在实例上定义,而不是在类上定义。

关于python - 在类实例和类定义上调用类装饰器有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65214486/

相关文章:

python - 什么时候调用类装饰器?

python - python中yield值存储在哪里

python - 为什么当 Python venvs 也有 python.exe 文件时,它们的配置中有 "home"设置?

python - 同一窗口中的matplotlib数字序列

django - 装饰器失败时显示错误消息

python - 从装饰类访问静态字段

jquery - 在 flask 中检查 request.method 时出错

python - 如何使用 python-decorator 包来装饰类方法?

python - 在装饰器的包装器中访问 kwargs 和 args