__init__ __new__区别

__init__与__new__区别:

__new__:创设对象时调用,会重回当前指标的二个实例

摘要

正文切磋了Python中__init____new__方法。

__new____init__不无不一样的功用。而且对于Python的新类和旧类来讲意义也不如。

1 class A(object):
2     def __init__(self,*args, **kwargs):
3         print "init A"
4     def __new__(cls,*args, **kwargs):
5         print "new A %s"%cls
6      #return super(A, cls).__new__(cls, *args, **kwargs)
7         return object.__new__(cls, *args, **kwargs)

请运转代码:

__init__在python,其实是,在实例化之后推行的,用来起头化一些性格,约等于构造函数,不过又不平等

__init__:创制完对象后调用,对日前目的的有些实例开始化,无重临值

__new____init__作用上的区分

__new____init__的机要不同在于:__new__是用来创设四个类的实例的(constructor卡塔 尔(英语:State of Qatar),而__init__是用来发轫化一个实例的(initializer卡塔尔国。

说明

class A:
    def __init__(self):
        print "A.__init"

    def __new__(self):
        print "A.__new"


class B(object):
    def __init__(self):
        print "B.__init"
        super(B, self).__init__()

    def __new__(cls):
        print "B.__new__"
        return super(B,cls).__new__(cls)


a = A()
b = B()
print(type(a))
print(type(b))

密切一些,通过参数会有所察觉,其实__init__(self)
 self隐式的将,实例传过来。

1、在类中,如果__new__和__init__并且设有,会优先调用__new__

Python的新类和旧类

Python中的类分为新类和旧类。旧类是Python3事先的类,旧类并不是暗中同意世襲object类,而是继续type类。

Python第22中学的旧类如上面代码所示:

class oldStyleClass: # inherits from 'type'
    pass

Python第22中学定义叁个新类:

class newStyleClass(object): # explicitly inherits from 'object'
    pass

在Python3中装有的类均暗中认可世袭object,所以并无需显式地内定object为基类。

object为基类能够使得所定义的类具有新类所对应的不二等秘书籍(methods)和属性(properties)。

在底下的篇章中我们会独家依据新类和旧类探究__new____init__

1、世襲自object的风靡类才有__new__

运维结果

 

>>> class Data(object):
...     def __new__(self):
...             print "new"
...     def __init__(self):
...             print "init"
... 
>>> data = Data()
new

__new____init__参数的两样

__new__所吸收接纳的第多个参数是cls,而__init__所收到的率先个参数是self。那是因为当我们调用__new__的时候,该类的实例还并不设有(也正是self所援引的目标还不设有卡塔 尔(英语:State of Qatar),所以要求吸取八个类作为参数,进而爆发多个实例。而当我们调用__init__的时候,实例已经存在,由此__init__接受self作为第2个参数并对该实例进行要求的初步化操作。那也代表__init__是在__new__今后被调用的。

2、__new__最少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别

A.__init
B.__new__
B.__init
<type ‘instance’>
<class ‘__main__.B’>

__new__在python中实际是,在实例化早前执行的,那些通过参数雷同能够看来

2、__new__方法会再次回到所协会的靶子,__init__则不会。__init__无再次来到值。

Python旧类中的__new____init__

Python的旧类中实际并从未__new__措施。因为旧类中的__init__其实起构造器的功效。所以假若大家定义如下旧类:

class oldStyleClass:
    def __new__(cls):
        print("__new__ is called") # this line will never get called during construction

oldStyleClass()

次第输出结果如下:

<__main__.oldStyleClass instance at 0x109c45518>

看得出创立及开首化对象的经过并未调用__new__。实际上,除非显式调用:oldStyleClass.__new__(oldStyleClass),该类中的__new__方法中的内容永久不会被调用。因为旧类构造实例并不会调用__new__方法。

但假设我们重载__init__方法:

class oldStyleClass:
    def __init__(self):
        print("__init__ is called")

oldStyleClass()

该程序将会输出

__init__ is called
<__main__.oldStyleClass instance at 0x1091992d8>

意气风发经大家在__init__中加上return讲话,将会促成TypeError: __init__() should return None的错误。

class oldStyleClass:
    def __init__(self):
        return 29

oldStyleClass()

前后相继结果如下:

TypeError: __init__() should return None

那象征对于Python的旧类来讲,大家不可能调节__init__函数的再次回到值。

3、__new__务须要有再次回到值,重返实例化出来的实例,那点在大团结达成__new__时要特别注意,能够return父类(通过super(当前类名,
cls)卡塔尔__new__出去的实例,恐怕间接是object的__new__出来的实例

请在乎:  A无基类,B有基类并且__new__
方法跟__init__四个办法有两点不相同

__new__(cls),cls是隐式的传递的类对象,而不是实例。因为__new__的职责就是,创造类实例并重临实例。

>>> class Data(object):
...     def __init__(cls):
...             cls.x = 2
...             print "init"
...             return cls
... 
>>> data = Data()
init
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'Data'

>>> class Data(object):
...     def __new__(cls):
...             print "new"
...             cls.x = 1
...             return cls
...     def __init__(self):
...             print "init"
... 
>>> data = Data()
new
>>> data.x =1 
>>> data.x
1

If __new__() returns an instance of cls, then the new instance’s __init__() method will be 
invoked like __init__(self[, ...]), where self is the new instance and the remaining 
arguments are the same as were passed to __new__().

如果__new__返回一个对象的实例,会隐式调用__init__

If __new__() does not return an instance of cls, then the new instance’s __init__() method
 will not be invoked.

如果__new__不返回一个对象的实例,__init__不会被调用

Python新类中的__new____init__

Python的新类允许客商重载__new____init__措施,且那多少个艺术具有不一致的作用。__new__用作构造器,起创造多少个类实例的意义。而__init__作为开端化器,开头阶化二个已被创设的实例的功效。

如上面代码是所示:

class newStyleClass(object): 
    # In Python2, we need to specify the object as the base.
    # In Python3 it's default.

    def __new__(cls):
        print("__new__ is called")
        return super(newStyleClass, cls).__new__(cls)

    def __init__(self):
        print("__init__ is called")
        print("self is: ", self)

newStyleClass()

结果如下:

__new__ is called
__init__ is called
self is: <__main__.newStyleClass at 0x109290890>
<__main__.newStyleClass at 0x109290890>

创立类实例并初阶化的经过中__new____init__被调用的次第也能从上边代码的输出结果中来看:__new__函数首先被调用,构造了叁个newStyleClass的实例,接着__init__函数在__new__函数再次来到一个实例的时候被调用,何况那个实例作为self参数被盛传了__init__函数。

那边须要介怀的是,假设__new__函数再次回到二个早已存在的实例(无论是哪位类的卡塔 尔(阿拉伯语:قطر‎,__init__不会被调用。如下边代码所示:

obj = 12 
# obj can be an object from any class, even object.__new__(object)

class returnExistedObj(object):
    def __new__(cls):
        print("__new__ is called")
        return obj

    def __init(self):
        print("__init__ is called")

returnExistedObj()

施行结果如下:

__new__ is called
12

还要另二个须要注意的点是:

假诺大家在__new__函数中不回来任何对象,则__init__函数也不会被调用。

如上面代码所示:

class notReturnObj(object):
    def __new__(cls):
        print("__new__ is called")

    def __init__(self):
        print("__init__ is called")

print(notReturnObj())

施行结果如下:

__new__ is called
None

足见尽管__new__函数不回去对象的话,不会有任何对象被成立,__init__函数也不会被调用来开始化对象。

4、__init__有三个参数self,便是那些__new__再次回到的实例,__init__在__new__的底蕴上得以成功部分别样开头化的动作,__init__无需再次来到值

1.self,cls参数分裂,即 __new__为classmethod.

class temp(object):

    def __init__(self,txt):
        self.txt = txt
        print '__init__'


    def __new__(cls,txt):
        print '__new__'
        print txt
        return super(temp,cls).__new__(cls)

temp('what?')

以下摘自《Python宗旨编程(第二版卡塔 尔(英语:State of Qatar)》:

计算几个点

  1. __init__不能够有重回值

  2. __new__函数直接上能够再次回到别的类的实例。如上边例子中的returnExistedObj类的__new__函数重回了二个int值。

  3. 只有在__new__回来二个新创立归于此类的实例时当前类的__init__才会被调用。如上边例子所示:

class sample(object):
    def __str__(self):
        print("sample")

class example(object):
    def __new__(cls):
        print("__new__ is called")
        return sample()

    def __init__(self):
        print("__init__ is called")

example()

输出结果为:

__new__ is called
sample

5、如果__new__创办的是眼前类的实例,会自行调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来作保是当下类实例,即使是别的类的类名,;那么实际上创立再次回到的正是别的类的实例,其实就不会调用当前类的__init__函数,也不会调用其余类的__init__函数。

2.__new__有return。

结果:

__init()__ “构造器”方法:

当类被调用,实例化的第一步是创立实例对象。大器晚成旦目的创设了,Python
检查是否贯彻了__init__()方法。暗许情状下,若无概念(或隐蔽卡塔尔国特殊措施__init__(),对实例不会施加任何非常的操作.任何所需的特定操作,都急需技师完结__init__(),覆盖它的私下认可行为。假设__init__()未有完成,则赶回它的指标,实例化进程甘休。
然而,如果__init__()已经被完成,那么它将被调用,实例对象作为第一个参数(self)被传送步入,像职业措施调用同样。调用类时,传进的其它参数都提交了__init__()。实际中,你能够想像成那样:把创设实例的调用当成是对构造器的调用。
不问可见,(a)你未曾经过调用 new 来创建实例,你也从不定义一个构造器。是
Python 为你创立了目标; (b)
__init__(),是在解释器为您创设一个实例后调用的首先个方法,在你早先应用它前边,这一步能够让您做些计划职业。
__init__()是不胜枚举为类定义的特有措施之风姿罗曼蒂克。此中有的特种方式是预订义的,缺省状态下,不实行任何操作,比方__init__(),要定制,就非得对它举行重载,还会有个别方法,只怕要按须要去落到实处。

 

那五个难点牵涉到概念New-style and classic
classes。请参考
style clas,两个是怎么冒出的。

C:\Python27\python.exe D:/weixin/temp/abc.py
__new__
what?
__init__

Process finished with exit code 0
__new()__ “构造器”方法:

与__init__()相比,__new__()方法更像二个真正的构造器。类型和类在本子
2.2 就集结了,Python
客户能够对内建项目实行派生,由此,需求黄金年代种门路来实例化不可变对象,例如,派生字符串,数字,等等。
在这里种意况下,解释器则调用类的__new__()方法,一个静态方法,况兼传入的参数是在类实例化操作时生成的。__new__()会调用父类的__new__()来创立对象(向上代理卡塔尔国。
缘何大家认为__new__()比__init__()更像构造器呢?那是因为__new__()必得回到三个法定的实例,这样解释器在调用__init__()时,就足以把那一个实例作为
self 传给它。调用父类的__new__()来创建对象,正像别的语言中应用 new
关键字同样。
__new__()和__init__()在类创造时,都不胫而走了(相近卡塔尔国参数。13.11.3
节中有个例子使用了__new__()。

<class '__main__.B'>
>>> class A(object):
...     def __new__(Class):
...             object = super(A,Class).__new__(Class)
...             print "in New"
...             return object
...     def __init__(self):
...             print "in init"
... 
>>> A()
in New
in init
<__main__.A object at 0x7fa8bc622d90>
>>> class A(object):
...     def __new__(cls):
...             print "in New"
...             return cls
...     def __init__(self):
...             print "in init"
... 
>>> a = A()      
in New

object.__init__(self[, ...])
Called when the instance is created. The arguments are those passed to the class 
constructor expression. If a base class has an __init__() method, the derived 
class’s __init__() method, if any, must explicitly call it to ensure proper initialization 
of the base class part of the instance; for example: BaseClass.__init__(self, [args...]). 
As a special constraint on constructors, no value may be returned; doing so will cause a
TypeError to be raised at runtime.

在对象的实例创建完成后调用。参数被传给类的构造函数。如果基类有__init__方法,子类必须显示
调用基类的__init__。

从没再次来到值,不然会再抓住TypeError错误。
原文:https://www.cnblogs.com/gsblog/p/3368304.html

在继承派生时的调用顺序

不管是new style恐怕classic都能够动用isinstance(obj, cls)做判断。

 

1 class B(A):
2     def __init__(self,*args, **kwargs):
3         print "init B"
4     def __new__(cls,*args, **kwargs):
5         print "new B %s"%cls
6      #return super(B, cls).__new__(cls, *args, **kwargs)
7         return object.__new__(cls, *args, **kwargs)

因为a尽管实际type
‘instance’。不过查看a.__class__照例能够看看a的种类。

 

 

 

Linux and
python学习调换1,2群已满.

1、在概念子类时从没重新定义__new__()时,Python私下认可是调用该类的直接父类的__new__()方法来布局该类的实例,假设此类的父类也从不重写__new__(),那么将直接按此规矩追溯至object的__new__()方法,因为object是负有新式类的基类。

Linux and
python学习调换3群新开,款待参加,一同学习.qq 3群:563227894

2、而如若子类中重写了__new__()方法,那么您能够自由选择大肆贰个的其它的新式类(一定借使新式类,唯有新型类必定都有__new__(),因为具备最新类皆以object的后人,而精髓类则从未__new__()方法)的__new__()方法来制作实例,包括那个新式类的保有前代类和后代类,只要它们不会促成递归死循环。反正确定无法调用自身的__new__,这早晚是死循环。

不前行,不倒退,截止的情状是未曾的.

3、对于子类的__init__,其调用准绳跟__new__是同样的,当然假设子类和父类的__init__函数都想调用,能够在子类的__init__函数中参加对父类__init__函数的调用。

同台发展,与君共勉,

4、大家在选取时,尽量采用__init__函数,不要去自定义__new__函数,因为那四头在世袭派生时的特色依然特别不形似的。

 

 

__new__ 的作用

1、__new__方法重就算当您世袭部分不可变的class时(比方int,
str, tuple), 提须要你二个自定义这个类的实例化进程的不二等秘书技。

若是大家须要二个永恒都以正数的偏分头类型,通过集成int,大家可能会写出那样的代码。

1 class PositiveInteger(int):
2     def __init__(self, value):
3         super(PositiveInteger, self).__init__(self, abs(value))
4 
5 
6 i = PositiveInteger(-3)
7 print i

但运营后会开掘,结果根本不是我们想的那么,大家任然得到了-3。那是因为对于int这种
不可变的对象,大家只有重载它的__new__方法技能起到自定义的法力。
这是修正后的代码:

class PositiveInteger(int):
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))


i = PositiveInteger(-3)
print i

透过重载__new__方法,大家兑现了索要的效用。

2、达成单例

实则,当大家理解了__new__主意后,大家还是能运用它来做一些别的轶事体,比如完成设计形式中的 单例形式(singleton) 。
因为类每二次实例化后发出的经过都以透过__new__来决定的,所以经过重载__new__办法,我们能够很简短的达成单例形式。

class Singleton(object):
    def __new__(cls):
        # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance


obj1 = Singleton()
obj2 = Singleton()


obj1.attr1 = 'value1'
print obj1.attr1, obj2.attr1
print obj1 is obj2

输出结果:
value1 value1
True
可以见见obj1和obj2是同八个实例。

class Singleton(object):
    __instance = None


    def __init__(self, *args, **kwargs):
        pass


    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            # if not hasattr(cls, 'instance'):
            cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
            cls.__instance.aa = args[0]
            print type(cls), type(cls.__instance), type(cls.__instance.aa)
        return cls.__instance

obj1 = Singleton(1, 2, 3, b=2)
obj2 = Singleton(1, 2, 3, b=2)

obj1.attr1 = 'value1'
obj2.attr2 = 'value2'
print obj1.attr1, obj1.attr2
print obj1 is obj2
print obj1.aa, obj2.attr1 

结果:
<type ‘type’> <class ‘__main__.Singleton’> <type
‘int’>
value1 value2
True
1 value1

 

3、达成自定义的metaclass。

 

 

仿照效法链接:

 

相关文章