【发布时间】:2021-11-27 16:04:09
【问题描述】:
在调试一些代码时,我使用 @property 装饰器发现了一个意外行为。简化版如下:
class TestClass:
@property
def __len__(self):
return 6
test_instance = TestClass()
print(len(test_instance))
我希望这会打印 6,但我得到一个 TypeError:TypeError: 'int' object is not callable
没有属性装饰器,这可以正常工作。我也可以print(test_instance.__len__) 没有问题。我正在努力弄清楚为什么会出现这种情况,并希望有人能用简单的术语来解释它。
编辑: 对于非 dunder 方法,这也可以按我的预期工作:
class TestClass:
@property
def foobar(self):
return 6
test_instance = TestClass()
print(test_instance.foobar)
6 按预期打印。我的理解是len(Class) 是调用__len__ 方法的语法糖,这就是我在这里感到困惑的原因
【问题讨论】:
-
你为什么期望它打印
6?您希望它如何工作? -
你为什么要把 dunder 方法变成属性?你到底想解决什么?
len(obj)致电obj.__len__()。试图使__len__成为属性本质上等同于6()(至少在这种情况下),因此关于int的错误不是callable -
属性用于编写一些东西,就好像它是一个属性一样,并让它调用一个方法。如果获取对象长度的正常方法是
obj.__len__,那么您的尝试将起作用。但由于它通常是一种方法,因此您不需要属性。