Python中新式类与经典类的区别详析
作者:BlackMatrix 发布时间:2022-02-04 05:11:16
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)
从代码运行结果看,恰巧与从左至右的广度优先预期结果相同。
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassC'>, <class '__main__.NewStyleClassA'>, <type 'object'>]
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)
运行结果不再符合广度优先:
[<class '__main__.SubNewStyleClass'>, <class '__main__.NewStyleClassB'>, <class '__main__.NewStyleClassA'>, <class '__main__.NewStyleClassC'>, <type 'object'>]
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类型
<type 'list'>
内置类的实例类型和经典类的实例类型完全不同,容易造成困惑,不利于代码的统一。
这个问题在Python 3之后就不复存在了,因为Python3中所有的类都是新式类,新式类中类与类型已经统一:类实例的类型是这个实例所创建自的类(通常是和类实例的__class__相同),而不再是Python 2.x版本中的“instance”实例类型。
更详细的:https://www.jb51.net/article/165048.htm
来源:https://www.cnblogs.com/blackmatrix/p/5630515.html
猜你喜欢
- 在上一篇文章中,简单介绍了下闭包(closure)和原型链,现在继续来研究闭包的内部机制。对了,所有的东西都参考自这篇文章:Javascri
- 本文实例为大家分享了Python KNN分类算法的具体代码,供大家参考,具体内容如下KNN分类算法应该算得上是机器学习中最简单的分类算法了,
- 调用数据库存储过程见下:<%Set Dataconn = Server.CreateObject(&qu
- 前言本文提供将视频按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。环境依赖ffmpeg环境安装,可以参考文章:windows ffmp
- 项目地址是:https://www.chenshiyang.com/dytk接下来我们分析下源码简要看下实现原理。实现原理该项目不需要使用模
- 1.高阶函数# 1.变量指向函数# 调用函数和函数本身print("-10的绝对值为:",abs(-10))print(
- 1 、创建一个django项目使用django-admin.py startproject MyDjangoSite 参考这里2、建立视图f
- 1. lock互斥锁知识点:lock.acquire()# 上锁lock.release()# 解锁#同一时间允许一个进程上一把锁 就是Lo
- 印象中最早看老外个人网站就挺纳闷,怎么人家都没有www,这样也可以?经过不断尝试,我发现确实不录入www要快捷的多,但不清楚怎么能做到。几年
- MySQL GUI Tools是一套图形化桌面应用工具套装,可以用来管理MySQL服务器。该套装工具包含三个工具:MySQL Query B
- 前言最近微信小游戏跳一跳大热,自己也是中毒颇久,无奈手残最高分只拿到200分。无意间看到教你用Python来玩微信跳一跳一文,在电脑上利用a
- 一、 在数据库排序查询优化上的差异。在讲解这个内容之前,为了读者能够清楚我讲的内容,我要先谈一个概念。命中率,它是指从内存中取得数据而不从磁
- ASP+javascript实现可显示和隐藏的树型菜单实例:<script language=&qu
- getatter()通过方法名字符串调用方法,这个方法最主要的作用就是实现反射机制,也就是说可以通过字符串获取方法实例,这样就可以把一个类可
- 随着JS与XHTML的应用普及,越来越多的web界面应用技术出现在网站上,比如我们常见的日历控件,搜索下拉框等,这些web界面应用技术大大的
- 错误的代码①d = {'a':1, 'b':0, 'c':1, 'd':0}
- 前阵子刚完成一个B/S架构的学校办公系统,体会就是表太多,文件太多,而每个文件中类似的操作(代码)也太多了,例如学生信息和教师信息操作,st
- 代码如下: <% '屏蔽主流的下载工具 Dimxurl,xtool '获取浏览器AGENT xurl=lcase(Re
- 本文实例讲述了PHP调用全国天气预报数据接口查询天气。分享给大家供大家参考,具体如下:基于PHP的聚合数据全国天气预报API服务请求的代码样
- 示例:# -*- coding:utf-8 -*-import jsonstrtest = {"中故宫":"好