foo.__x__ 和 x(foo) in Python 的原因(即 len 和 __len__)
The reason of foo.__x__ and x(foo) in Python (i.e. len and __len__)
直觉上 List
class 应该实现一个属性或方法来检索实例的长度。幸运的是 Python'lists 有一个名为 __len__
的隐藏方法。不幸的是,这种方法并不意味着可以直接使用。我应该改用一个外部函数来为我读取隐藏的方法。
这就像我需要请别人打开冰箱给我拿啤酒一样。啤酒在冰箱里,我有两只手,我应该能自己搞定。
从概念上讲,这种方法似乎很奇怪。为什么没有用于获取列表长度的属性(而不是方法)。
换句话说,我更喜欢使用foo.len
而不是foo.len()
或foo.__len__
。 len(foo)
对我来说似乎更奇怪。
这个实现有解释吗?
这 answer 部分回答了我的问题,但我仍然感到沮丧。
你可以找到一个深刻的理由here and Guido's thoughts here。
总结一下,这是因为它们可能并不像您想象的那样密切相关。只是谈论 post 的 len
与 __len__
,但您可以在第一个 link.
中找到其他示例
让我们先关注__len__
:
class Test1:
pass
class Test2:
def __bool__(self):
return False
class Test3:
def __len__(self):
return 0
t1 = Test1()
t2 = Test2()
t3 = Test3()
现在 t1
、t2
¹ 和 t3
在布尔上下文中的计算结果是什么?
bool(t1)
是 True
。标准 python 行为,任何未明确 False
的行为都被视为 True
.
bool(t2)
是 False
。将对象显式设置为 False
会相应地表现。
bool(t3)
是 False
。因为 t3
implements __len__
被认为是一个容器,因为它的长度是 0
那么它是一个空容器。根据定义,空容器在布尔上下文中被视为 False
。
__len__
不一定只被 len
.
调用
len
,另一方面,为您提供保证:
- 它将return一个正整数;
- 它适用于任何容器,而不仅仅是列表;
它将计算该容器中的元素数。不管它意味着什么取决于容器:compare
s = "A string with "
d = s.encode("utf-8")
print(len(s)) # outputs 15
print(len(d)) # outputs 18
因为s
是字符的容器而d
是字节的容器。
¹ 请注意 __bool__
在 python2 中是 __nonzero__
。
直觉上 List
class 应该实现一个属性或方法来检索实例的长度。幸运的是 Python'lists 有一个名为 __len__
的隐藏方法。不幸的是,这种方法并不意味着可以直接使用。我应该改用一个外部函数来为我读取隐藏的方法。
这就像我需要请别人打开冰箱给我拿啤酒一样。啤酒在冰箱里,我有两只手,我应该能自己搞定。
从概念上讲,这种方法似乎很奇怪。为什么没有用于获取列表长度的属性(而不是方法)。
换句话说,我更喜欢使用foo.len
而不是foo.len()
或foo.__len__
。 len(foo)
对我来说似乎更奇怪。
这个实现有解释吗?
这 answer 部分回答了我的问题,但我仍然感到沮丧。
你可以找到一个深刻的理由here and Guido's thoughts here。
总结一下,这是因为它们可能并不像您想象的那样密切相关。只是谈论 post 的 len
与 __len__
,但您可以在第一个 link.
让我们先关注__len__
:
class Test1:
pass
class Test2:
def __bool__(self):
return False
class Test3:
def __len__(self):
return 0
t1 = Test1()
t2 = Test2()
t3 = Test3()
现在 t1
、t2
¹ 和 t3
在布尔上下文中的计算结果是什么?
bool(t1)
是True
。标准 python 行为,任何未明确False
的行为都被视为True
.bool(t2)
是False
。将对象显式设置为False
会相应地表现。bool(t3)
是False
。因为t3
implements__len__
被认为是一个容器,因为它的长度是0
那么它是一个空容器。根据定义,空容器在布尔上下文中被视为False
。
__len__
不一定只被 len
.
len
,另一方面,为您提供保证:
- 它将return一个正整数;
- 它适用于任何容器,而不仅仅是列表;
它将计算该容器中的元素数。不管它意味着什么取决于容器:compare
s = "A string with " d = s.encode("utf-8") print(len(s)) # outputs 15 print(len(d)) # outputs 18
因为
s
是字符的容器而d
是字节的容器。
¹ 请注意 __bool__
在 python2 中是 __nonzero__
。