2014-11-05 64 views
0

我來自一個堅實的Java(和Matlab)背景,並且最近一直試圖自學Python(3.4)。在Java API文檔(http://docs.oracle.com/javase/7/docs/api/)中,特定類的文檔始終顯示該類祖先的完整概述(請參閱,例如this screenshot)。如何獲得類型/類的Python層次結構的概述?

現在我想知道是否有任何方法查看Python類的類似祖先層次結構。我的工作假設是,由於Python是一種面向對象的語言,所有非原始類型都將是對象(請糾正我,如果我錯了)。瞭解不同類型的祖先應該可以大大幫助我理解可迭代,序列,視圖和列表。

我已經嘗試了幾件事情,正如對類似問題的回答(如here)中的建議;但inspect.mro(cls)似乎並不總是工作;例如,下面給出了一個錯誤:

inspect.getmro(dict_keys)

即使dict_keys是一種類型:

In[30]: type({}.keys()) Out[30]: dict_keys

我也非常驚訝地得知,列表不會從迭代繼承:

In[34]: inspect.getmro(list) Out[34]: (list, object)

所以,雖然我的問題主要是如何查看(並且理想地瀏覽)標準Python庫的層次結構,關於如何理解默認類型層次結構的任何其他評論,主要是列表/序列/視圖/ iterables如何正式關聯,也是非常受歡迎的。看起來,(另外優秀的)Python教程並沒有真正涵蓋這個東西。

+0

* Python中的所有內容都是一個對象。 – Ffisegydd 2014-11-05 16:26:55

+0

是的,@Ffisegydd,這正是我工作的假設:)然而,爲什麼'type({}。keys())'產生'dict_keys',但做'dict_keys'產生'name dict_keys沒有被定義'... – EelkeSpaak 2014-11-05 16:31:56

+0

概述在https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy – 2014-11-05 21:08:16

回答

2

僅僅因爲某些東西是一個類型並不意味着您在全局命名空間中引用了該類型。 dict_keys就是這種情況。例如

>>> inspect.getmro(type({}.viewkeys())) # using python2.x :-(
(<type 'dict_keys'>, <type 'object'>) 

所以它確實有一個MRO,是檢查的 - 你只是沒有對dict_keys型手柄前了。

注意,MRO可以是一個有點自欺欺人:

>>> import collections 
>>> issubclass(list, collections.Iterable) 
True 

,所以我們看到,list至少認爲這是collections.Iterable一個子類,即使你不會在MRO找到它。這是因爲collections.Iterable實際上是register本身使用abc模塊。

我認爲這是python和java之間的基本區別之一。在python中,你通常更關心對象提供的接口,而不是實際的類型和繼承樹。在某種程度上,這個陳述看起來有些迂腐 - 畢竟,你需要知道繼承樹來知道對象提供的接口。但是,我們在接口中工作的事實正是爲什麼tuplelistgenerator對象可以迭代,儘管沒有真實的公共基類(collections.Iterable不計算爲虛擬基類)高於object(它可以不會被迭代)。

+0

啊謝謝,至少應該回答我的一部分困惑。考慮一下,如果我沒有明確地導入它,如果當然有意義的話dict_keys不存在於全局命名空間中。儘管如此,它仍然留下了是否存在瀏覽類層次結構的便利方式的問題。但是我開始懷疑Python的層次結構比Java更復雜,與「虛擬子類」等等有關。:)在Java中,每個類(除了Object)都只有一個父類,並且還可以實現任意數量的接口。這可能會誤導我。 – EelkeSpaak 2014-11-05 16:40:31

+0

@EelkeSpaak:事實上,Java的基本設計選擇之一是僅支持單一繼承。 Python允許多重繼承。 mgilson的答案用簡單英語的方式提到了「接口」,但是當然Java有一個名爲'interface'的實際語言結構,它可以被認爲使得類關係複雜化,使人想起多重繼承。最終,雖然我確實認爲Java的某些知識可以幫助學習Python,但您必須小心謹慎,不要過於相似。 – 2014-11-05 17:38:33

+0

@JohnY - 謝謝。不幸的是,我不太瞭解Java,所以我不能把事情做得太遠。我的意思是「接口」在單詞的朗讀意義上。當然,這也是一個正式的概念,而我所談論的卻不太正式。 – mgilson 2014-11-05 19:32:58