前面的文章中,我们提到了在Python中一切皆对象,理所当然的,函数和类也是对象,所以,函数和类在Python中也是一等公民。既然,一切皆对象,对象与类的关系是实例化与抽象的关系。那么,这些对象,是什么类型的呢,也就是说,是由什么类实例化出来的呢?这些对象所属的类之间的继承关系又是怎样的?今天这篇文章中,我们来重点探究一下,Python中的标准类型层次结构,从而回答上面的两个问题。在开始之前,需要再次明确区分一下“继承”与“实例化”这两种关系的区别,不然可能会不小心被绕进去,毕竟类也是对象,可以称之为类对象。
继承:是类与类之间的关系,子类继承父类,这时候,我们只关注类的概念,暂时不考虑类对象的概念。
实例化:是类与对象之间的关系,类可以理解为一个模板,是一个抽象化的实体,对象是基于类这个模板实例化出来的具体的对象。由于类也是对象,所以,谈到实例化时,我们也会探究类对象是有什么类实例化来的。
基础知识为了更好的能看到对象与类、类与类之间的关系,我们需要一些前置知识。对这些知识,只需要知道、会用即可,这里不需要深究,后面多用,会有更多地体会。
type前面的文章中,我们经常提到使用type()函数,可以查看一个对象的类型,这个说法其实是不对的。在今天这篇文章中,我们要转变一下观念了,type不是函数,而是一个类!首先看下builtins中的type定义:
如果没有看过定义,估计有不少初学者或者新手把type当作一个内置的函数。
看定义中的说明文档,我们发现type这个类的初始化函数,可以获取类对象,初始化函数接收的参数,可以是一个对象,也可以是更多的参数。接下来,简单演示一下type类的用法:
执行结果:
此外,从文档看出,我们还可以通过type自定义类对象:
属性__class__我们知道对象是由类实例化的,前面,我们通过type这个类找到了实例化某个对象的类。如果,不借助type,我们能否通过一个对象本身找到实例化它的类呢?答案是肯定的。在Python中,对象都有一个特殊的属性:class,通过这个属性,我们也可以获得实例化该对象的类对象:
执行结果:
既然__class__属性指向了一个类对象,我们自然可以通过__class__属性进行实例化对象的操作。
属性__bases__不管是type类,还是__class__属性,我们要找的都是对象与类之间的关系,也就是实例化关系。接下来,我们来看一下类与类之间的继承关系。由于,类也是对象,也就是类对象,类对象也是有自己的属性的,其中__bases__就是指向这个类对象的父类对象的属性。由于Python中的面向对象是支持多继承的,一个子类可以有多个父类,所以__bases__属性,属性名是一个复数的形式,该属性是一个元组:
执行结果:
需要注意的是,只有类对象才有__bases__属性,普通对象必须先找到自身的类对象,才能进一步找到父类。
可以结合前面通过type类自定义类,来进一步看这个类对象的继承关系:
执行结果:
Python标准类型层次结构先说几个关键的结论:1、Python中所有的类对象,都是通过type类实例化的;2、Python中所有的类对象的最顶层的父类都是object;3、object这个类对象是由type类实例化的;4、type这个类对象是由type类自己实例化的。
有点绕,暂时有个概念,以实践慢慢消化理解吧。
关于Python标准类型的层次结构图,附在本文的结尾。
接下来,通过代码演示常见标准类型的层次结构:
执行结果:
Python中的标准类型层次结构示意图:
由于篇幅有限,并没有涵盖Python中的完整的类型层次结构。