我来自扎实的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教程并没有真正涵盖这些东西,似乎。
答案 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中,您通常更关心对象提供的接口,而不是实际的类型和继承树。在某种程度上,这个陈述似乎有点迂腐 - 毕竟,你需要知道继承树才能知道对象提供的接口。但是我们在接口中工作的事实正是为什么tuple
,list
和generator
对象可以迭代,尽管没有真正的公共基类(collections.Iterable
没有算上它是object
以上的虚拟基类)(不能迭代)。