【发布时间】:2020-05-15 21:23:52
【问题描述】:
这对我来说似乎是一个错误,我无法真正弄清楚为什么。
我有一个非常简单的自定义 LinkedList 类:
class MyLinkedList:
def __init__(self):
self.head = None
def __iter__(self):
self.currNode = self.head
return self
def __next__(self):
if self.currNode:
res = self.currNode
self.currNode = self.currNode.next
return res
else:
raise StopIteration
def addAtHead(self, val: int) -> None:
currNode = self.head
self.head = Node(val, currNode)
问题来自 iter 方法。在我将 head 节点添加到空的linkedList 后,iter 仍然认为 self.head 为 None!在调试节点中,我可以看到 self.head 是一个有效的 not none 实例,但是在将其值分配给 self.currNode 之后,self.currNode 原来是 None。
我认为这可能是属性问题,所以我将属性更改为属性。但问题仍然存在。我哪里错了?
@property
def head(self):
return self._head
@head.setter
def head(self, x):
self._head = x
添加我的调用堆栈:
ll = MyLinkedList()
ll.addAtTail(6)
ll.addAtHead(5)
ll[0] # is None
#where a __getitem__ is defined as:
def __getitem__(self, i):
n = 0
for node in self:
if n == i:
return node
n += 1
raise IndexError
class Node:
def __init__(self, val=None, next=None):
self.val = val
self.next = next
【问题讨论】:
-
不要让列表成为自己的迭代器。一些教程建议这样做,但这是一个非常糟糕的主意,因为如果您尝试使用嵌套循环或同时或可重入地迭代列表,它会中断。
-
"iter 仍然认为 self.head 是 None!"我不明白;您显示的调试器屏幕截图清楚地显示了
head = {Node} ...。无论如何,您能否展示一个尝试使用导致意外错误的类 的示例? IDE 并不总是能正确处理所有事情,或者它们可能会显示不同步的内容。 -
您需要展示您如何使用它(使用minimal reproducible example)以便我们提供完整的答案,但主要问题可能是您还没有编写迭代器类。迭代器必须具有幂等的
__iter__方法(在 99.99% 的情况下,它们应该什么都不做,但return self),因为 Python 假设它可以在现有的迭代器上愉快地调用__iter__并且什么都不做。如果您希望这是一个 iterable,则不应定义__next__,并且通常将__iter__编写为生成器函数(将所有逻辑迁移到__iter__并使用 @987654334 @ 其中__next__将使用return)。 -
@user1438644:那是另一回事。该节点不应该是一个迭代器。
-
我无法重现您的问题,但也许我正在做一些与您不同的事情,因为很难说出您到底在运行什么。我使用了第一个块中的
MyLinkedList类,并在最后一个块中添加了__getitem__方法。我还从您的最后一个块创建了Node类。然后最后一个块中的其余代码工作正常。当我执行ll[0]时,我得到了一个节点。
标签: python