使用 @属性 装饰器和 dunder 方法

Using the @property decorator and dunder methods

在调试一些代码时,我发现使用 @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__ 方法的语法糖,这就是我在这里感到困惑的原因

len 尝试调用 test_instance.__len__,但现在它是 属性,属性访问的计算结果为 6,而不是函数。

如果您只是想让 TestClass 的实例的硬编码长度为 6,请不要使用 属性。

class TestClass:
    def __len__(self):
        return 6