python3 class object_class object和没有object的区别

Python

的类分为经典类与新式类。Python2.7之前的版本中可以采用经典类,经典类继承父类的顺序采用深度优先算法,但在Python3之后的版本就只承认新式类了。新式类在python2.2之后的版本中都可以使用,新式类的继承顺序采用C3算法,其继承顺序可以通过查看MRO列表获取。

经典类与新式类的区别

经典类是默认没有派生自某个基类的,而新式类默认派生自object基类:

1

2

3

4

5

6

7

# old style

class A():

pass

# new style

class A(object):

pass

经典类在类多重继承的时候是采用的从左至右深度优先的匹配方法,而新式类采用C3算法(不同于广度优先)进行匹配的。

经典类没有__MRO__和instance.mro()调用,而新式类有。

经典类中的继承问题

经典类中采用深度优先的匹配方法,可能导致在查询继承树中绕过后面的父类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class D():

def foo(self):

print "class D"

class B(D):

pass

class C(D):

def foo(self):

print "class C"

class A(B, C):

pass

f = A()

f.foo()

其输出为:class D。

新式类采用C3算法(区别于广度优先的原则)进行搜索,若使用新式类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class D(object):

def foo(self):

print "class D"

class B(D):

pass

class C(D):

def foo(self):

print "class C"

class A(B, C):

pass

f = A()

f.foo()

输出为:class C 搜索的顺序如下图所示:

C3算法

C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。

本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。

单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。

深度优先搜索用栈(stack)来实现,整个过程可以想象成一个倒立的树形:

把根节点压入栈中。

每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。

找到所要找的元素时结束程序。

如果遍历整个树还没有找到,结束程序。

广度优先搜索使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:

把根节点放到队列的末尾。

每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。

找到所要找的元素时结束程序。

如果遍历整个树还没有找到,结束程序。

对于同一段程序:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class A(object):

def foo(self):

print "A"

class B(A):

def foo(self):

print "B"

class C(B):

def foo(self):

print "C"

class D(A):

def foo(self):

print "D"

class E(D):

def foo(self):

print "E"

class F(C, E):

def foo(self):

print "F"

f = F()

f.foo1()

当使用深度优先搜索,广度优先搜索及C3算法的不同搜索顺序如下:

DFS深度优先搜索(FCBAED)

BFS广度优先搜索(FCEBDA)

C3算法(FCBEDA)

对于新式类,可以用instance.__mro__或instance.mro()来查看其MRO(Method

Resolution Order 方法解析顺序)列表。对于上文代码中的类F的MRO如下:

1

2

print F.mro()

(, , , , , , )

即C3算法的解析结果。

同时为了解决多重继承中的调用父类问题,python2.2之后引入了super。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值