gpt4 book ai didi

python - 为什么在自定义迭代器上隐式调用 __len__()

转载 作者:太空狗 更新时间:2023-10-29 21:31:34 24 4
gpt4 key购买 nike

我正在编写一个简单的链表实现如下:

class Node(object):
def __init__(self, value):
self.value = value
self._next = None

def __iter__(self):
here = self
while here:
yield here
here = here._next

def __len__(self):
print("Calling __len__ on: {}".format(self))
return sum(1 for _ in self)

def append_to_tail(self, value):
if self._next is None:
self._next = Node(value)
else:
self._next.append_to_tail(value)

def print_list(ll):
print(ll.value)
if ll._next:
print_list(ll._next)

my_list = Node('a')
my_list.append_to_tail('b')
my_list.append_to_tail('c')

print_list(my_list)

这段代码在没有 __len__ 方法的情况下运行良好。删除这三行并运行上面的代码输出:

  first
second
third

但是,如果存在 __len__ 方法,则结果为:

    first
Calling __len__ on: <__main__.Node object at 0x108804dd0>
Calling __len__ on: <__main__.Node object at 0x108804dd0>
<snip>
Calling __len__ on: <__main__.Node object at 0x108804dd0>
Calling __len__ on: <__main__.Node object at 0x108804dd0>
Traceback (most recent call last):
File "len_example.py", line 31, in <module>
print_list(my_list)
File "len_example.py", line 24, in print_list
if ll._next:
File "len_example.py", line 14, in __len__
return sum(1 for _ in self)
File "len_example.py", line 14, in <genexpr>
return sum(1 for _ in self)
File "len_example.py", line 8, in __iter__
while here:
File "len_example.py", line 14, in __len__
return sum(1 for _ in self)
File "len_example.py", line 14, in <genexpr>
return sum(1 for _ in self)
<snip>
File "len_example.py", line 8, in __iter__
while here:
File "len_example.py", line 13, in __len__
print("Calling __len__ on: {}".format(self))
RuntimeError: maximum recursion depth exceeded while calling a Python object

请注意输出中存在 firstprint_list() 执行一次,但在递归之前隐式调用了 __len__() 方法。什么在调用该方法?

我在 python 3.3.1 和 2.7.3 中看到了相同的行为

最佳答案

您在 bool 上下文中使用此处:

while here:

这将使用 __len__ 来查看它是否是一个空容器(例如是 false-y),参见 Truth Value Testing :

Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:

[...]

  • instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False.

对于您的用例,请改用 is not None:

while here is not None:

关于python - 为什么在自定义迭代器上隐式调用 __len__(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25291590/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com