关于检查对象是否为 Python 中的迭代器的示例的混淆
Confusion about one example to check if an object is an iterator in Python
我在 Whosebug 上阅读了一些关于如何在 Python 中检查对象是否为迭代器的帖子,但它们似乎没有解决我的问题。我从书中有这个例子有效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!
为什么这一行要检查变量 numbers 是否是一个迭代器?当 visits = [15, 35, 80] 时,iter(numbers) is iter(numbers)
应该是真的吗?
当您调用 iterable 时,对此类对象调用 iter()
将始终生成 new 迭代器对象。但是在 迭代器 上调用 iter()
将始终 return 相同的对象;这是 iterator protocol 的要求。
来自iterator.__iter__()
documentation:
Return the iterator object itself. This is required to allow both containers and iterators to be used with the for
and in
statements.
因为iter(iterable)
总是returns 自身,所以测试iter(obj) is iter(obj)
会为真;在这两种情况下,同一个对象被 returned。
为了帮助您理解 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
,在 numbers
上调用 iter
将始终 return 个内部相同的对象:iter(numbers) is iter(numbers)
将是 True
.
我在 Whosebug 上阅读了一些关于如何在 Python 中检查对象是否为迭代器的帖子,但它们似乎没有解决我的问题。我从书中有这个例子有效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!
为什么这一行要检查变量 numbers 是否是一个迭代器?当 visits = [15, 35, 80] 时,iter(numbers) is iter(numbers)
应该是真的吗?
当您调用 iterable 时,对此类对象调用 iter()
将始终生成 new 迭代器对象。但是在 迭代器 上调用 iter()
将始终 return 相同的对象;这是 iterator protocol 的要求。
来自iterator.__iter__()
documentation:
Return the iterator object itself. This is required to allow both containers and iterators to be used with the
for
andin
statements.
因为iter(iterable)
总是returns 自身,所以测试iter(obj) is iter(obj)
会为真;在这两种情况下,同一个对象被 returned。
为了帮助您理解 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
,在 numbers
上调用 iter
将始终 return 个内部相同的对象:iter(numbers) is iter(numbers)
将是 True
.