Python装饰器与实例方法同名

时间:2015-11-12 02:26:22

标签: python python-decorators

我对this提出了一个非常类似的问题,除了我想命名我的函数property

所以例如我喜欢做类似的事情:

class ThingWithProperties(object):

    def property(self, a):
        print("in property", a)

    @property
    def test(self):
        print("in test")

t = Testing()
t.property(1)
t.test()

但是我收到以下错误:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    class ThingWithProperties(object):
  File "test.py", line 10, in ThingWithProperties
    @property
TypeError: property() missing 1 required positional argument: 'a'

有人可以解释为什么会这样吗?以及如何解决它(没有重命名我的实例方法)?

1 个答案:

答案 0 :(得分:2)

这种情况正在发生,因为通过定义一个名为property的方法,您将在类声明的范围内隐藏内置property。因此,当您编写@property时,系统会调用您的方法来装饰test而不是内置property

您可以使用__builtin__模块明确使用内置property

class ThingWithProperties(object):

    def property(self, a):
        print("in property", a)

    @__builtin__.property
    def test(self):
        print("in test")

虽然我个人总是避免阴影内置,即使它们只是在有限的范围内被遮蔽,就像这里的情况一样。

为了更清楚地了解正在进行的“阴影”,请尝试在翻译中运行:

foo = 42
print(foo)

class Test:
    foo = 73
    print(foo)

print(foo)

这里有两点要说明:首先,有些人可能会惊讶于我们可以在类定义中print。关键是类定义是一个像其他任何代码块一样的代码块,您可以编写for - 循环和print所有您想要的,并且您创建的任何变量或函数将被收集到一起实际创建类时,类字典。

第二点是类定义创建了一个新范围,范围内foo的值与外部不同。也就是说,上面会再次打印42,然后是73,然后是42