我已经阅读了有关如何检查对象是否是Python中的迭代器的stackoverflow上的一些帖子,但似乎它们没有解决我的问题。我在 Effective Python
一书中有这个例子def normalize_defensive(numbers):
if iter(numbers) is iter(numbers): # An iterator — bad!
raise TypeError(‘Must supply a container’)
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
使用:
visits = [15, 35, 80]
normalize_defensive(visits) # No error
visits = ReadVisits(path) # ReadVisits is a class with an __iter__ method.
normalize_defensive(visits) # No error
it = iter(visits)
normalize_defensive(it)
>>>
TypeError: Must supply a container
所以我的问题就在这一行:
if iter(numbers) is iter(numbers): # An iterator — bad!
为什么这行检查变量号是否是迭代器?当访问次数= [15,35,80]时,iter(numbers) is iter(numbers)
答案 0 :(得分:2)
当您调用 iterable 时,在这样的对象上调用iter()
将始终生成 new 迭代器对象。但是在迭代器上调用iter()
将始终返回相同的对象;它是iterator protocol的要求。
来自iterator.__iter__()
documentation:
返回迭代器对象本身。这是允许容器和迭代器与
for
和in
语句一起使用所必需的。
由于iter(iterable)
始终返回本身,因此测试iter(obj) is iter(obj)
将为真;在这两种情况下都返回相同的对象。
答案 1 :(得分:0)
为了帮助您了解Martijn的解释,请查看以下内容:
>>> numbers = [15, 35, 80]
>>> it = iter(numbers)
>>> it2 = iter(numbers)
>>> it3 = iter(it)
>>> id(it1)
51123792
>>> id(it2)
51056464 # id of it2 is different from it1
>>> id(it3)
51123792 # iterator of iterator it3 has the same id as iterator it1
因此,如果numbers
是iterator
,则iter
上的numbers
调用将始终返回内部相同的对象:iter(numbers) is iter(numbers)
将为True
}。