Python object和type

发布于 2020-05-31  641 次阅读


这里说的object和type不是内置函数object()和type()

Python中万物皆对象

先记住这句话,type继承object、object是type的实例化(有点晕。。。到底是哪个先存在,有点像鸡和蛋的问题)

Python中有两种关系

  • 类对象关系,顶点为type
  • 集成关系,顶点为object

类对象关系(Type)

__class__方法查看当前对象所属的类,亦即由哪个类实例化而成。

继承关系(Object)

__base__方法查看当前类的父类,亦即继承自哪个类。

>>> a=A()
>>> A.__base__
<class 'object'>
>>> a.__class__
<class '__main__.A'>
>>> print('==============================================')
==============================================
>>> object.__base__    # object的父类为空
>>> object.__class__
<class 'type'>
>>> type.__base__
<class 'object'>
>>> type.__class__
<class 'type'>

已上例子可以看到,普通类的父类是object,object的父类是空,object的类型是type,type的父类是object、type的类型是type。

在Python的世界中,object是父子关系的顶端,所有数据类型的父类都是object;type是类型关系实例的顶端,所有的对象都是它的实例。

我们再引入list, dict, tuple 这些内置数据类型来看看:
>>> list.__bases__
(<type 'object'>,)
>>> list.__class__
<type 'type'>
>>> dict.__bases__
(<type 'object'>,)
>>> dict.__class__
<type 'type'>
>>> tuple.__class__
<type 'type'>
>>> tuple.__bases__
(<type 'object'>,)
它们的父类都是object,类型都是type。

借用某博客里的一张图片,他们的关系应该是这样的(蓝色表示继承,红色表示类型)

白板上的第一列,目前只有type,我们先把这列的东西叫Type。
白板上的第二列,它们既是第三列的类型,又是第一列的实例,我们把这列的对象叫TypeObject。
白板上的第三列,它们是第二列类型的实例,而没有父类(__bases__)的,我们把它们叫Instance。

你以为事情就这样完了?不。。看见type孤零零在第一列其实不是那么舒服。。我们给它整几个玩伴看看。但要怎么整呢?要属于第一列的,必须是type的子类,那么我们只需要继承type来定义类就可以了:
>>> class M(type):
... pass
...
>>> M.__class__
<type 'type'>
>>> M.__bases__
(<type 'type'>,)
>>>
嗯嗯,M类的类型和父类都是type。这个时候,我们可以把它归到第一列去。那么,要怎么样实例化M类型呢?实例化后它应该出现在那个列?嗯嗯,好吧,刚才你一不小心创建了一个元类,MetaClass!即类的类。如果你要实例化一个元类,那还是得定义一个类:
>>> class TM(object):
... __metaclass__ = M # 这样来指定元类。
...
...
>>> TM.__class__
<class '__main__.M'> # 这个类不再是type类型,而是M类型的。
>>> TM.__bases__
(<type 'object'>,)

好了,现在TM这个类就是出现在第二列的。

再总结一下:
第一列,元类列,type是所有元类的父亲。我们可以通过继承type来创建元类。
第二列,TypeObject列,也称类列,object是所有类的父亲,大部份我们直接使用的数据类型都存在这个列的。
第三列,实例列,实例是对象关系链的末端,不能再被子类化和实例化。

参考文章地址: https://www.zhihu.com/question/38791962


一名测试工作者,专注接口测试、自动化测试、性能测试、Python技术。