这篇博客主要描述Python的新风格对象(new-style objects),如下:
- <type 'type'>和<type 'object'>分别是什么?
- 用户自定义的类和实例之间是怎么联系的?它们和内置类型又是怎么联系的?
- 什么是元类(metaclasses)?
New-style表明这篇博客所说的内容只适用于版本为2.2及以上的python。
开始之前
最主要,是理解type和object的区别与联系。我们平时用的最多的是Object,比如你定义一个类时,会继承object:
>>> class Test(object):
... pass
这里你定义了一个自定义类Test
,不难看出,Test
继承了object
,也就是说,object
是Test
的超类(或者说基类)。
接下来,你可以再定义一个类:
>>> class subTest(Test):
... pass
subTest
继承了Test
,同时,因为Test
继承了object
,所以也可以说subTest
继承了object
。在这里涉及到一个重要的知识点,那就是继承具有传递性。如果你仔细观察,你会发现另外一个知识点,那就是:object
是所有类的超类(这句话至关重要)。那type是什么呢?它是object的类型(也就是说object是type的实例),同时,object又是type的超类。
“type是object的类型,同时,object又是type的超类”这句话看起来就充满疑点:那到底是先有object还是先有type呢?其实,“先有object和还是type问题”就像“先有鸡还是先有蛋问题”。到底先有谁呢?不急,请继续看:
你要明白这些,先要知道,python是面向对象的语言。在python里面,一切皆为对象。
一切皆为对象?这里对于一部分人来说,可能不是很容易理解。这么说吧,在python里,
int
整形是对象,整数2
也是对象,你定义的函数啊,类啊都是对象,你定义的变量也是对象。总之,你在python里能用到的都可以称之为对象。
好了,把python里一切皆为对象给整明白后,你要明白在面向对象的体系中,存在两种关系:
- 父子关系(图中以实线描述):这种关系存在于某个类(subclass)是另一个类(superclass)的特别版本之中。通常描述为“子类是一种父类”。比如:蛇是一种爬行动物(Snake is a kind of reptile)。其中,蛇(snake)是子类,爬行动物(reptile)是父类。蛇拥有爬行动物的特征,同时,又拥有标志自己是一条蛇的特征。
- 类型实例关系(图中以虚线描述):这种关系存在于两个对象之中,其中一个对象(实例)是另一个对象(类型)的具体实现。我有一条宠物蛇叫Squasher,那么Squasher就是蛇的一个实例。英文描述为:"Squasher is an instance of snake".
用实线表示父子关系,是因为父与子的关系更加“贴实”。比如有人叫你列出有关蛇的词,你可能会说蛇是爬行动物
,但你不会说出蛇是Squasher
....
我想如果把上面的两种关系用代码表示出来你会更加直观:
>>> class reptile(object):
... feature = "有标志自己是爬行动物的特征"
... name = "爬行动物"
...
>>> class snake(reptile):
... snake_feature = "除了有标志自己是爬行动物特征,还有自己是蛇的特征"
... name = "蛇"
...
>>> Squasher = snake()
class reptile(object)
和class snake(reptile)
就是代表父子关系。object是reptile的基类,reptile是snake的超类(基类)。这里有没有想起来 object
是所有类的超类?Squasher = snake()
是类型实例关系。将类snake实例化就得到了Squasher。
这时候,有两条很有用的规则:
- Dashed Arrow Up Rule:If X is an instance of A, and A is a subclass of B, then X is an instance of B as well.翻译过来应该是“虚线向上规则”:如果X是A的实例,同时A又是B的子类,那么,X也是B的实例。;
- Dashed Arrow Down Rule:If B is an instance of M, and A is a subclass of B, then A is an instance of M as well.翻译过来应该是“虚线向下规则”:如果B是M的实例,同时A是B的子类,那么,A也是M的实例。其实这条规则很少会用到,但却和这篇博客要讲的内容息息相关。我来略作分析,从“如果B是M的实例”这句话得出,B是
实例
,“A是B的子类” --> B是一个(父)类
。B是实例,同时又是一个类?怎么回事?看完这篇博客,你会知道答案的。
在这里,我来解释一下为什么叫"虚线向上规则",通过观察上图右边,我们可以清晰地见到一个带箭头的虚线,从X端出发,射向A端,此时