我正在编写一个简单的链表实现,如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
没有__len__方法,此代码运行正常.删除这三行并运行上面的代码输出:
first
second
third
Run Code Online (Sandbox Code Playgroud)
但是,如果__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
Run Code Online (Sandbox Code Playgroud)
注意first输出中是否存在.print_list()执行一次,但__len__()在递归之前隐式调用该方法.什么叫这种方法?
我看到python 3.3.1和2.7.3的相同行为
Mar*_*ers 11
您正在here布尔上下文中使用:
while here:
Run Code Online (Sandbox Code Playgroud)
这将用于__len__查看它是否为空容器(例如是假y),请参阅真值测试:
任何对象都可以用于真值进行测试,用于在使用
if或while病症或如下面的布尔运算的操作数.以下值被视为false:[...]
- 用户定义的类的实例,如果类定义了一个
__nonzero__()或__len__()方法,则该方法返回整数零或bool值False.
对于您的用例,请is not None改用:
while here is not None:
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
137 次 |
| 最近记录: |