写这篇文章的原因就是因为看到这两条像是绕口令的推文,其中的两个主角分别是type和object
注意:以下内容仅适用于Python3,Python2在类的定义上有很大区别,故不在讨论范围内
背景知识
- 在Python中一切皆object,要么是class instance,要么是metaclass instance
>>> isinstance(type,object) True >>> isinstance(object,object) True >>> isinstance('abc',object) True >>> isinstance([1,2,3],object) True >>> isinstance(list,object) True >>> isinstance(str,object) True >>> isinstance((),object) True
- object之间的关系只存在两种
-
继承
>>> class a(): ... pass # b继承a >>> class b(a): ... pass >>> b.__base__ <class '__main__.a'> >>> isinstance(b, a) False
-
实例化
>>> class a(): ... pass >>> class b(a): ... pass # c实例化b >>> c = b() >>> isinstance(c, a) True >>> isinstance(c, b) True >>> c.__class__ <class '__main__.b'>
-
用到的工具
- isinstance()
该函数是用来判断一个object是否是一个已知类型,返回True或者False。
与type()函数类似,但区别在于isinstance()会考虑继承关系
参考:https://docs.python.org/3/library/functions.html#isinstance - type()
该函数返回一个object的type,且返回值的type仍为type
与isinstance()函数类似,但区别在于type()不会考虑继承关系
type()函数与oject.__class__相似
参考:https://docs.python.org/3/library/functions.html#type - class.__base__
该属性返回class object的base class
参考:https://docs.python.org/3/library/stdtypes.html#class.bases - instance.__class__
该属性返回class instance所属的类
与type()函数功能类似
参考:https://docs.python.org/3/library/stdtypes.html#instance.class
object
首先说一下object
所有的类都继承自object
且所有对象一定是某一个类的实例
>>> class a():
... pass
>>> a.__base__
<class 'object'>
>>> class b(a):
... pass
>>> b.__base__
<class '__main__.a'>
object也是type元类的实例,它自己没有父类
>>> type(object)
<class 'type'>
>>> object.__base__
type
所有类对象都是type元类的实例
>>> class a():
... pass
>>> class b(a):
... pass
>>> type(a)
<class 'type'>
>>> type(b)
<class 'type'>
>>> type(int)
<class 'type'>
>>> type(str)
<class 'type'>
type元类也是对象,它是它自己的实例
>>> type(type)
<class 'type'>
type的父类是object,即type继承自object
>>> type.__base__
<class 'object'>
总结
综上,type元类和object类就是Python世界的奇点,type元类实例化出来了它自己以及object类,从此就通过实例化和继承产生无穷的object。
正所谓“太极生两仪 两仪生四象 四象生八卦 八卦演万物”