为何给__len__双下方法加@property装饰器后调用len()会抛TypeError
核心原因
你对len(实例)是调用__len__的语法糖的认知是对的,但你忽略了内置函数调用魔法方法的固定逻辑,和你直接访问属性的逻辑不一样,可以用个通俗的类比理解:
正常情况下类的__len__是个饺子机,按照Python的约定,要按开关(调用方法)才能得到饺子(长度值)。你给它加@property装饰器的操作,相当于直接把饺子机换成了已经做好的饺子(整数6)。
- 你自己直接访问
test_instance.__len__,相当于直接拿饺子,自然没问题,和你写的普通属性foobar的运行逻辑完全一致。 - 但
len()是个按死规矩做事的机器人,它拿到__len__对应的东西之后,一定会先按开关(调用)才拿结果,现在它拿到的是饺子不是饺子机,按开关自然就报错了,也就是你看到的'int' object is not callable。
你可以自己验证:哪怕不用len(),你直接写print(test_instance.__len__()),给访问到的整数6手动加括号调用,一样会报完全相同的错误。
补充说明
不是双下方法不能加@property,而是如果这个双下方法的官方协议约定本身就是「需要被调用才能返回结果」,你就不能把它改成直接返回结果的属性,否则内置函数、语法糖按约定去调用它的时候就会出错。
内容的提问来源于stack exchange,提问作者JamNCheez
相关产品推荐
相关产品推荐

