如何获得类型/类的Python层次结构的概述?

时间:2014-11-05 16:26:02

标签: python python-3.x

我来自扎实的Java(和Matlab)背景,最近一直在尝试自学Python(3.4)。在Java API文档(http://docs.oracle.com/javase/7/docs/api/)中,特定类的文档总是显示该类祖先的一个很好的概述(参见例如this screenshot)。

现在我想知道是否有任何方法可以查看Python类的类似祖先层次结构。我的假设是,由于Python是一种面向对象的语言,所有非原始类型都是对象(如果我错了,请纠正我)。理解不同类型的祖先应该可以极大地帮助我理解可迭代,序列,视图和列表。

我已经尝试了几件事,正如在回答类似问题时所建议的那样(例如here);但inspect.mro(cls)似乎并不总是有效;例如,以下内容给出了错误:

inspect.getmro(dict_keys)

即使dict_keys是一个类型:

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

我也非常惊讶地发现列表不会从iterable继承:

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

所以,虽然我的问题主要是关于如何查看(并且理想地,浏览)标准Python库的层次结构,但是关于如何理解默认类型的任何其他评论'层次结构,主要是list / sequences / views / iterables如何正式关联,也非常受欢迎。 (其他优秀的)Python教程并没有真正涵盖这些东西,似乎。

1 个答案:

答案 0 :(得分:2)

仅仅因为某个类型并不意味着您在全局命名空间中引用了该类型。这是dict_keys的情况。 e.g。

>>> 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以上的虚拟基类)(不能迭代)。