2014-11-05 63 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