據我所知,標準說它確實存在,但我試圖找到這個原因。爲什麼Python Iterator需要一個簡單地返回self的iter方法?
如果它只是始終返回self
有什麼必要呢?
很顯然你總是可以訪問該對象,因爲你是那個對象上調用iter
,有啥需要擁有它?
據我所知,標準說它確實存在,但我試圖找到這個原因。爲什麼Python Iterator需要一個簡單地返回self的iter方法?
如果它只是始終返回self
有什麼必要呢?
很顯然你總是可以訪問該對象,因爲你是那個對象上調用iter
,有啥需要擁有它?
想象一下,你想寫一個遍歷任何類型的迭代代碼。通常情況下你只寫了for
陳述或理解,但讓我們而是明確做什麼for
在幕後做,以使事情變得更加明顯:
i = iter(iterable)
while True:
try:
val = next(i)
except StopIteration:
break
else:
do_stuff(val)
如果你不這樣做第一線,你的代碼韓元不適用於列表,字符串,元組或其他任何東西,但迭代器。
但是,如果你做的第一線,很好,iter(iterable)
最好返回一個迭代器,或者你的代碼不會與迭代工作。
你可能想知道爲什麼iter
不能沒有這個做正確的事情?畢竟,這確實因爲有__len__
和__getitem__
但沒有__iter__
對象時有它的魔力來創建一個迭代器,那麼爲什麼不能也有魔法剛剛返回它的參數,如果它有一個__next__
但沒有__iter__
?這是一個語言設計問題,但一般來說,Python試圖儘可能少用魔法。使迭代不順序的魔力是必要的,因爲在將迭代協議添加到語言之前,這樣的序列存在(在廣泛的第三方代碼中),並且爲了簡化事情的小好處而去除太難了。
這樣的for
循環和其他需要與iterables一起工作的代碼可以無條件地調用iter
來迭代它們,而不是分別處理迭代器和其他迭代器。特別是,非迭代器可能合理地有一個名爲next
的方法,我們希望能夠將它們與迭代器區分開來。
這不是因爲非迭代器可能有一個名爲'next'的方法。 (當然這也許就是爲什麼'next'被重命名爲'__next__')。 – abarnert
for
0123應該使用迭代器,因此for i in something:
會自動調用iter(something)
來獲取迭代器並遍歷所述迭代器。現在,如果迭代器並沒有太多可迭代(即沒有定義__iter__
),你不能使用for
循環迭代器,即:
items = [1, 2, 3]
# this would work
for item in items: pass
# this wouldn't
it = iter(items)
for item in it: pass
因此,迭代器應該是iterables了。另一種方式,「以某種方式檢測」迭代器,而不是調用iter
對他們來說,是hacky和脆弱的(你會如何決定?)。
你決定這樣做的方式 - 就像python-ideas每年提出一次或兩次提議(並且被拒絕)一樣簡單:如果'在執行回退到基於索引的迭代之前,首先檢查是否存在「i .__ next__」,如果是,則返回「i」。 – abarnert
@abarnert難道不是因爲缺乏一個更好的措辭,「hacky and fragile」? ;-) – delnan
這個改變將會是'iter'實現中幾行簡單明顯的代碼。多人編寫了一些補丁,這些補丁在第一次嘗試時就能夠正常工作並通過完整的測試套件,這意味着它不是那麼脆弱。真正的問題在於它使得語言太「神奇」,使得鍵入更容易,但更難以學習和掌握。 – abarnert
__iter__()
旨在通過對象返回一個迭代。對於已經是迭代器的對象,什麼是迭代器?當然是self
。
迭代器是一個遍歷迭代器的迭代器,不管它是一個迭代器,而不是它本身,就像列表包含其他值一樣,而不是(必然)它本身。無論如何,爲什麼「iter(an_iterator)」甚至被定義?爲什麼它*有*被定義? (有很好的理由,但你沒有任何名稱)。 – delnan
@delnan:答案已經說:「你平時只是用'for'語句(或理解)......這確實在幕後的代碼。」這是否需要更清楚? – abarnert
我想我只是錯過了那部分。這可能表明它需要更多突出顯示,或者我需要仔細閱讀:-) – delnan
@delnan:好的,新版本更好嗎? – abarnert