最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • python新式类和经典类的区别有哪些

    正文概述    2020-01-13   333

    python新式类和经典类的区别有哪些

    1、新式类与经典类

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

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

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

    2、继承顺序的区别

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

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

    相关推荐:《Python基础教程》

    对经典类进行代码验证(所有经典类的代码必须在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”实例类型。


    下载网 » python新式类和经典类的区别有哪些

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元