Python 为什么在自定义迭代器上隐式调用_len__;()
我正在编写一个简单的链表实现,如下所示:Python 为什么在自定义迭代器上隐式调用_len__;(),python,Python,我正在编写一个简单的链表实现,如下所示: 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 de
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)
此代码在没有\uuu len\uuu
方法的情况下运行良好。删除这三行并运行上述代码输出:
first
second
third
但是,如果存在\uuuu len\uuu
方法,则结果为:
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
首先
在以下位置调用“len”:
在以下位置调用“len”:
在以下位置调用“len”:
在以下位置调用“len”:
回溯(最近一次呼叫最后一次):
文件“len_example.py”,第31行,在
打印列表(我的列表)
打印列表中第24行的文件“len_example.py”
如果是,下一步:
文件“len_example.py”,第14行,in__len__
返回和(1表示uu自身)
文件“len_example.py”,第14行,在
返回和(1表示uu自身)
iter中第8行的文件“len_example.py”__
在这里:
文件“len_example.py”,第14行,in__len__
返回和(1表示uu自身)
文件“len_example.py”,第14行,在
返回和(1表示uu自身)
iter中第8行的文件“len_example.py”__
在这里:
文件“len_example.py”,第13行,in__len__
打印(“调用{}.format(self))
RuntimeError:调用Python对象时超出了最大递归深度
注意输出中是否存在第一个print\u list()
执行一次,但在递归之前,有东西隐式调用了\uu len\uuu()
方法。这个方法叫什么
我看到python 3.3.1和2.7.3的行为与您在布尔上下文中使用的相同:
while here:
这将使用\uuuu len\uuuu
查看它是否为空容器(例如为false-y),请参阅:
任何对象都可以测试真值,用于if
或while
条件,或作为下面布尔运算的操作数。以下值被认为是错误的:
[……]
- 用户定义类的实例,如果该类定义了一个
\uuuu非零\uuuuuuuuuu()
或\uuuuuuu len\uuuuuuuuu()
方法,则该方法返回整数零或布尔值False
李>
对于您的用例,请使用而不是None
:
while here is not None: