2014-10-27 32 views
0

zip爲例。 我只想知道它是Iterable還是IteratorGenerator在Python中查看實例的類層次結構

所以我把這個:

zip(x,y).__class__ 

它打印:ZIP
爲什麼類名是小寫?

import inspect 
inspect.getmro(zip) 
zip.__base__ 

它打印:(拉鍊,對象)
那是不可能的。 Python doc表示zip返回iterator(或generator?),但zip顯然不是從Iterator或根據getmro打印的內容繼承而來。

所以這兩個問題,謝謝你的幫助。

+2

他們是農行的,它們不會出現在內置對象的MRO ... – 2014-10-27 14:33:26

+1

什麼都可以的迭代器。它不必從任何特定的基類型繼承;它只需提供正確的方法。 – khelwood 2014-10-27 14:39:59

+0

Python不太重視對象是什麼類型,它關心對象可以做什麼。 – 2014-10-27 16:14:15

回答

4

Python中的任何內容都不會從IteratorIterable繼承,因爲它們體現了協議。 Python尋找__iter__ and __next__ methods,而不是針對特定的基類。任何對象都可以是迭代器或迭代器,只需實現這些方法即可。

zip()是C代碼中定義的內置函數,它遵循所有內置函數的命名約定;這些總是小寫;它返回的類型在這裏並不完全相關,並且遵循函數名稱。

collections.abc.Iterablecollections.abc.Iterator類是抽象基類;他們實現special hooks,如果您正在測試的實例或子類實現所需的方法,則實質上會返回True

zip()既是可迭代(它有一個__iter__法)和迭代器(__iter__返回對象本身,它有一個__next__法):

>>> from collections.abc import Iterator, Iterable 
>>> zip_instance = zip('') 
>>> type(zip_instance) 
<class 'zip'> 
>>> isinstance(zip_instance, Iterator) 
True 
>>> isinstance((zip_instance, Iterable) 
True 
>>> zip_instance.__iter__ 
<method-wrapper '__iter__' of zip object at 0x10f2d8348> 
>>> zip_instance.__iter__() is zip_instance 
True 
>>> zip_instance.__next__ 
<method-wrapper '__next__' of zip object at 0x10f2d8348> 

zip()不是發電機,因爲它不」噸有任何special generator methods的:

>>> hasattr(zip_instance, 'send') 
False 
>>> hasattr(zip_instance, 'throw') 
False 
>>> hasattr(zip_instance, 'close') 
False 
+1

有關'zip'而不是'Zip'的說明:這就是很多內置類型的工作方式; Python和標準庫在一定程度上只符合PEP8。 – chepner 2014-10-27 14:52:05

+1

@chepner:PEP8指出應該尊重項目的當前約定,並且在CPython中,所有內置函數都是小寫字母。所以'zip()'是大寫的小寫字母。 – 2014-10-27 14:54:42

+0

更重要的是,zip()返回的東西的實際類型是不相關的。沒有人看過這門課。 zip()是小寫字母,因爲它用作函數。 – 2014-10-27 16:13:38