ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python新式类和经典类的区别

2019-03-02 19:49:14  阅读:263  来源: 互联网

标签:__ python object class init 实例 经典 new 新式



1,新式类和经典类的区别:广度优先和深度优先,这主要是在多类继承的时候会使用到,如下多类继承的D类对比:经典类在加载的时候采用的是深度优先算法,二新式类采用的是广度优先算法:比如经典类: 搜索顺序是(D,B,A,C)>>> class A: attr = 1...>>> class B(A): pass...>>> class C(A): attr = 2...>>> class D(B,C): pass...>>> x = D()>>> x.attr1
新式类继承搜索程序是宽度优先新式类:搜索顺序是(D,B,C,A)>>> class A(object): attr = 1...>>> class B(A): pass...>>> class C(A): attr = 2...>>> class D(B,C): pass...>>> x = D()>>> x.attr2(总结:1:经典类的深度优先,子类继承多个父类的时候,如果继承的多个类中有属性相同的,那么排在第一的父类的属性会覆盖后面继承的类的属性,也就是如果集成的多个父类属性相同,那么以继承的第一个父类的属性为主;2:新式类的广度优先算法:子类继承多个父类的时候,如果继承的多个父类中有属性相同的,那么越往后继承的类将会覆盖前面的类的属性,也就是后来的继承的覆盖前面的;真正发挥了长江后浪推前浪的传统)  3. 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。  4. 新式类增加了__getattribute__方法  5.新式类内置有__new__方法而经典类没有__new__方法而只有__init__方法注意:Python 2.x中默认都是经典类,只有显式继承了object才是新式类     而Python 3.x中默认都是新式类(也即object类默认是所有类的祖先),不必显式的继承object(可以按照经典类的定义方式写一个经典类并分别在python2.x和3.x版本中使用dir函数检验下。例如:class A():      pass    print(dir(A))会发现在2.x下没有__new__方法而3.x下有。接下来说下__new__方法和__init__的区别:在python中创建类的一个实例时,如果该类具有__new__方法,会先调用__new__方法,__new__方法接受当前正在实例化的类作为第一个参数(这个参数的类型是type,这个类型在c和python的交互编程中具有重要的角色,感兴趣的可以搜下相关的资料),其返回值是本次创建产生的实例,也就是我们熟知的__init__方法中的第一个参数self。那么就会有一个问题,这个实例怎么得到?注意到有__new__方法的都是object类的后代,因此如果我们自己想要改写__new__方法(注意不改写时在创建实例的时候使用的是父类的__new__方法,如果父类没有则继续上溯)可以通过调用object的__new__方法类得到这个实例(这实际上也和python中的默认机制基本一致),如:class display(object):    def __init__(self, *args, **kwargs):        print("init")    def __new__(cls, *args, **kwargs):        print("new")        print(type(cls))        return object.__new__(cls, *args, **kwargs)   a=display()运行上述代码会得到如下输出:new<class 'type'>init因此我们可以得到如下结论:在实例创建过程中__new__方法先于__init__方法被调用,它的第一个参数类型为type。如果不需要其它特殊的处理,可以使用object的__new__方法来得到创建的实例(也即self)。于是我们可以发现,实际上可以使用其它类的__new__方法类得到这个实例,只要那个类或其父类或祖先有__new__方法。class another(object):    def __new__(cls,*args,**kwargs):        print("newano")        return object.__new__(cls, *args, **kwargs)   class display(object):    def __init__(self, *args, **kwargs):        print("init")    def __new__(cls, *args, **kwargs):        print("newdis")        print(type(cls))        return another.__new__(cls, *args, **kwargs)   a=display()上面的输出是:newdis<class 'type'>newanoinit所有我们发现__new__和__init__就像这么一个关系,__init__提供生产的原料self(但并不保证这个原料来源正宗,像上面那样它用的是另一个不相关的类的__new__方法类得到这个实例),而__init__就用__new__给的原料来完善这个对象(尽管它不知道这些原料是不是正宗的) 

标签:__,python,object,class,init,实例,经典,new,新式
来源: https://www.cnblogs.com/qinjiting/p/10462573.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有