1.新式类与经典类

在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。

“新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。

官方文档 https://www.python.org/doc/newstyle/

2.继承顺序的区别

主要是在多重继承时才会遇到这个问题。

经典类的钻石继承是深度优先,即从下往上搜索;新式类的继承顺序是采用C3算法(非广度优先)。

对经典类进行代码验证(所有经典类的代码必须在Python2下运行,下同),ClassicClassB 继承自 ClassicClassA,SubClassicClass继承自ClassicClassB,ClassicClassC:

class ClassicClassA():

var = 'Classic Class A'

class ClassicClassB(ClassicClassA):

pass

class ClassicClassC():

var = 'Classic Class C'

class SubClassicClass(ClassicClassB, ClassicClassC):

pass

if __name__ == '__main__':

print(SubClassicClass.var)

在SubClassicClass对var属性进行搜索的过程中,根据从下到上的原则,会优先搜索ClassicClassB,而ClassicClassB没有var属性,会继续往上搜索ClassicClassB的超类ClassicClassA,在ClassicClassA中发现var属性后停止搜索,var的值为ClassicClassA中var的值;而ClassicClassC的var属性从始至终都未被搜索到。

从运行结果可以看出,输出的是Classic Class A,可见类继承的搜索是深度优先,由下至上进行搜索。

Classic Class A

新式类的继承顺序并非是广度优先,而是C3算法,只是在部分情况下,C3算法的结果恰巧与广度优先的结果相同。

对新式类的继承搜索顺序进行代码验证,新式类中,可以使用mro函数来查看类的搜索顺序(这也算是一个区别),如SubNewStyleClass.mro()。

class NewStyleClassA(object):

var = 'New Style Class A'

class NewStyleClassB(NewStyleClassA):

pass

class NewStyleClassC(NewStyleClassA):

var = 'New Style Class C'

class SubNewStyleClass(NewStyleClassB, NewStyleClassC):

pass

if __name__ == '__main__':

print(SubNewStyleClass.mro())

print(SubNewStyleClass.var)

从代码运行结果看,恰巧与从左至右的广度优先预期结果相同。

[, , , , ]

New Style Class C

但是不代表新式类的继承顺序就是广度优先,可以稍微修改下代码进行验证:NewStyleClassC改为继承自object

class NewStyleClassA(object):

var = 'New Style Class A'

class NewStyleClassB(NewStyleClassA):

pass

class NewStyleClassC(object):

var = 'New Style Class C'

class SubNewStyleClass(NewStyleClassB, NewStyleClassC):

pass

if __name__ == '__main__':

print(SubNewStyleClass.mro())

print(SubNewStyleClass.var)

运行结果不再符合广度优先:

[, , , , ]

New Style Class A

可见,新式类的继承顺序并非广度优先,而是C3算法。至于C3算法,以后再另外详细写。

3.类实例类型的区别

在经典类中,所有的类都是classobj类型,而类的实例都是instance类型。类与实例只有通过__class__属性进行关联。这样在判断实例类型时,就会造成不便:所有的实例都是instance类型。

class A():pass

class B():pass

a = A()

b = B()

if __name__ == '__main__':

print(type(a))

print(type(b))

print(type(a) == type(b))

type(a) == type(b)的结果永远为True,那这样的比较就毫无意义。

更为麻烦的是,经典类的实例是instance类型,而内置类的实例却不是,无法统一。

通过代码判断下内置类型list的实例[1, 2, 3]是什么类型

print(type([1, 2, 3]))

运行结果,是list类型

内置类的实例类型和经典类的实例类型完全不同,容易造成困惑,不利于代码的统一。

这个问题在Python 3之后就不复存在了,因为Python3中所有的类都是新式类,新式类中类与类型已经统一:类实例的类型是这个实例所创建自的类(通常是和类实例的__class__相同),而不再是Python 2.x版本中的“instance”实例类型。

更详细的:https://www.jb51.net/article/165048.htm

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

本文标题: Python中新式类与经典类的区别详析

本文地址: http://www.cppcns.com/jiaoben/python/265084.html

python3新式类_Python中新式类与经典类的区别详析相关推荐

  1. python中randint是什么意思_python中random.randint和random.randrange的区别详解

    在python中,通过导入random库,就能使用randint 和 randrange 这两个方法来产生随机整数.那这两个方法的区别在于什么地方呢?让我们一起来看看! 区别: randint 产生的 ...

  2. python定义数组并赋值_python中的数组赋值与拷贝的区别详解

    具体的注解我已经写在了程序里面:通俗的解释了python里面的浅拷贝与深拷贝的不同,请看程序. # -*- coding: utf-8 -*- import numpy as np import co ...

  3. python 多线程 类_Python中如何自定义一个多线程类呢?

    摘要: 下文讲述Python中自定义一个多线程类的方法分享,如下所示: 实现思路: 1.定义一个类继承threading.Thread 2.在自定义类中构造函数重写run方法 例: Python3中自 ...

  4. python什么时候用类_python中什么时候使用自定义类

    Python中所有的数据都是对象,它提供了许多高级的内建数据类型,功能强大,使用方便,是Python的优点之一.那么什么时候使用自定义类呢? 比如设计一个Person类,如果不使用自定义类,可以这样做 ...

  5. python新式类和经典类区别_Python中新式类和经典类的区别,钻石继承

    1)首先,写法不一样: class A: pass class B(object): 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. 3)新式类更符合OOP编程思想,统一了pyt ...

  6. python经典类和新式类_python中经典类和新式类的区别

    在定义class的时候,有几种常见的写法,比如: class A: pass class B(): pass class C(object): pass 在python 2中查看以上各个class的类 ...

  7. python经典类新式类_Python的新式类和经典类

    1. 前言 python在2.2版本中引入了descriptor功能,也正是基于这个功能实现了新式类(new-styel class)的对象模型, 同时解决了之前版本中经典类(classic clas ...

  8. Java中print、printf、println的区别 详解

    Java中print.printf.println的区别详解 printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和pr ...

  9. python random randint_python中random.randint和random.randrange的区别详解

    在python中,通过导入random库,就能使用randint 和 randrange 这两个方法来产生随机整数.那这两个方法的区别在于什么地方呢?让我们一起来看看! 区别: randint 产生的 ...

最新文章

  1. centeos7安装mariadb
  2. Request: Headless HTML rendering engine
  3. SQL提取表中某列字符长度为2的所有记录
  4. Android 应用中十大常见 UX 错误
  5. IOT(33)---NB-IOT通用物联解决方案
  6. Linux系统编程——vfork() 函数详解
  7. 萤石开放平台 .net c# sdk
  8. 系统功能测试思维导图
  9. python的认识从唯物主义_中国大学mooc用Python玩转数据章节答案
  10. 什么是IMS(IP多媒体子系统)
  11. 台式计算机怎么加声音,台式电脑音量加到最大还是没有声音怎么办,教你一招立马解决...
  12. CC26xx([CortexM3)的Power Reset and Clock
  13. 使用js调用接口导出excel
  14. 动态规划之神奇的口袋
  15. 单片机C语言步进电机实训报告,步进电机控制实训报告.doc
  16. 短视频头部效应加剧,秒拍整军三月强势归来
  17. 报表查询条件的正确打开方式,看到最后不禁会心一下
  18. 框架 也可以这样用 easy
  19. 【网络教程】同花顺公式编辑的基本语法,帮助说明
  20. Matlab学习-基本介绍

热门文章

  1. 【52. 贪心 - 排序不等式(排队打水)】
  2. java中excel文件的导入,限制上传的文件类型,文件的大小,显示上传文件的进度条...
  3. python 删除文件、清空目录的方法总结
  4. 手机端省市区三级联动
  5. java 手电筒_Android实现简单手电筒功能
  6. ARP是如何工作的?
  7. 我爱Flask之URL和Flask视图介绍
  8. Android的adb指令单刷boot、apk的方法
  9. HBase如何快速查询
  10. react-native Error installing Flipper-Glog