例如,假设我有一个用于迭代文件内记录的类:
class MySpecialFile:
...
def reset(self):
self._handle.seek(0)
def __iter__(self):
self.reset()
return self
答案 0 :(得分:1)
iter
应该没有副作用。通过违反这一假设,您的代码会破坏各种情况。例如,关于事物是否可迭代的标准测试:
try:
iter(thing)
except TypeError:
do_whatever()
将重置您的文件。同样,itertools consume
recipe:
def consume(iterator, n=None):
"Advance the iterator n-steps ahead. If n is None, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
将产生错误的文件位置,而不是在n
之后前进consume(your_file, n)
条记录。在循环之前用next
跳过前几条记录也会失败:
f = MySpecialFile(whatever)
next(f) # Skip a header, or try, anyway.
for record in f:
# We get the header anyway.
uhoh()
答案 1 :(得分:0)
任何颠覆语言构造的预期流程的行为都是危险的信号,比“代码气味”更糟。这不是特定于Python的。它适用于任何语言或系统。
但是,请记住关于“小头脑的妖精”的观点:
reset
是否改善了程序流程?如果您已经为需要理解和维护这一点的人们(包括您将来的自我)介绍了这些内容,那么reset
可能是一个好习惯。我对此表示怀疑,但是我已经在工作中看到过这种情况。
附带说明:为什么在初次构造迭代器时需要reset
?