当前位置:天才代写 > tutorial > Python教程 > python2中的__new__与__init__,新式类和经典类

python2中的__new__与__init__,新式类和经典类

2017-11-02 08:00 星期四 所属: Python教程 浏览:663

在python2.x中,从object担任得来的类称为新式类(如class A(object))不从object担任得来的类称为经典类(如class A())

新式类跟经典类的不同主要是以下几点:

  1. 新式类工具可以直接通过__class__属性获取自身范例:type

  2. 担任搜索的顺序产生了改变,经典类多担任时属性搜索顺序: 先深入担任树左侧,再返回,开始找右侧(即深度优先搜索);新式类多担任属性搜索顺序: 先程度搜索,然后再向上移动

例子:

经典类: 搜索顺序是(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.attr
1

新式类担任搜索措施是宽度优先

新式类:搜索顺序是(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.attr
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'>
newano
init

所有我们发明__new__和__init__就像这么一个干系,__init__提供出产的原料self(但并不担保这个原料来历正宗,像上面那样它用的是另一个不相关的类的__new__要领类获得这个实例),而__init__就用__new__给的原料来完善这个工具(尽量它不知道这些原料是不是正宗的)

 

    关键字:

天才代写-代写联系方式