博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python的新式类和经典类
阅读量:5738 次
发布时间:2019-06-18

本文共 1380 字,大约阅读时间需要 4 分钟。

问题

在Python中定义类时,我们经常看到两种写法:

class PersonOne:    name = "person one"    class PersonTwo(object):    name = "person two"

也就是说在Python中,继承object 与不继承object的写法有什么区别?

在Python2.X中,第一种写法称之为经典类,第二种写法称之为新式类。Python2.2之前只能支持第一种写法,在Python2.2到Python2.7,两种写法都可以,但是不同写法定义出来的类是不一样的;在Python3.X中两种写法都可以,而且定义出来的类是完全一样的,都是新式类,可以理解为和Java一样,Python3.0之后Object已经作为所有类的基类,因此是否显示指明已经不重要。因此,如果你是使用Python3.X的版本,完全可以无视这个问题,怎么写都行;但是如果不是就需要搞清楚区别了。

使用新式类和经典类的区别

个人理解,两种定义核心的区别就是定义类的MRO是不同的,在多重继承中,MRO直接决定了方法的调用顺序,因此会产生很大的影响。

  • 经典类的MRO

    经典类的MRO的生成时基于深度优先遍历算法的,以下面的继承关系为例,生成的MRO为:[D,B,A,C],因此,在调用test方法时,按照此顺序查找必然先找到A中的test方法,但是这其实是不太不合理的。

    class A:      def test(self):          print('in a test')  class B(A):      pass    class C(A):      def test(self):          print('in c test')    class D(B, C):       pass    if __name__ == '__main__':      d = D()       d.test()
  • 新式类的MRO
    在新式类中,MRO的生成时基于的,关于C3算法计算过程参见链接,核心就是Merge函数的计算过程,有的文章中直接说是广度优先其实并不准确。此处生成的类D的MRO为[D,B,C,A],那么,按照这个顺序调用test方法自然找到的是C中的test。

扩展

  1. super的调用关系

    在Python3中,我们经常使用到super方法,在单继承中没有什么疑问,直接调用super方法自然是访问其唯一的父类。但是再多继承中,又是如何决定调用哪一个父类的呢?这个还是和MRO有关。

    准确来说,super方法的调用方式为super(ClassName, self).func(),那么此处的func方法就是属于MRO中ClassName下一个类。如果确实没有参数,即super().func(),等价于super(MRO中的第一个类, self).func()
    还是以上面的继承关系为例,重写类D的__init__()方法,第一个super调用的是B,第二个是C。

    class D(B, C):    def __init__(self):        print("C")        super().__init__()        super(B, self).__init__()

转载地址:http://exfzx.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS 7下安装部署Oracle11g图文教程
查看>>
F#初学笔记06
查看>>
实战:将企业域名解析委派给企业DNS服务器
查看>>
在Lync 2013环境部署Office Web Apps
查看>>
微软大会Ignite,你准备好了么?
查看>>
读书笔记-高标管事 低调管人
查看>>
Master带给世界的思考:是“失控”还是进化
查看>>
用户和开发者不满苹果iCloud问题多多
查看>>
attrs.xml中declare-styleable 详解(用于自定义控件的属性)
查看>>
java.lang.UnsatisfiedLinkError:no dll in java.library.path终极解决之道
查看>>
错误“Unexpected namespace prefix "xmlns" found for tag LinearLayout”的解决方法(转)
查看>>
我的工具:文本转音频文件
查看>>
【许晓笛】从零开始运行EOS系统
查看>>
【跃迁之路】【460天】程序员高效学习方法论探索系列(实验阶段217-2018.05.11)...
查看>>
C++入门读物推荐
查看>>