python的__init__和__new__

本文全部實例代碼在python3.7下python

一.__new__和__init__區別

1.__new__先於__init__執行;__new__是至關於其餘OOP語言的構造方法,負責建立實例;以後,__init__負責初始化實例屬性。__new__處理對象建立,__ init__處理對象初始化。

2.__new__是一個特殊的靜態方法(沒有使用裝飾器 @staticmethod);由python解釋器調用,若是該類沒有__new__,則調用父類的__new__.

3.若是咱們建立一個類的實例,代碼以下:

class Foo:
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)

    def __init__(self, x, y):
        self.__x = x
        self.__y = y

foo = Foo(10, 20)

  

__init__返回爲None;
__new__返回了一個建立的實例,其後做爲__init__中的self傳入app

4.經過__new__建立實例,一般是

super().__new__(cls)

# cls爲當前要建立的類對象

5.若是__new__返回它本身的類的實例,那麼將使用實例做爲第一個被調用的__init__方法的self參數,__init__將隱式調用。
若是__new__方法返回除這個類以外的其餘實例,則不會調用實例__init__方法。在這種狀況下,您必須本身調用__init__方法。

看一個返回類實例以外的例子:blog

class Foo:
    def __init__(self, x):
        self.__x = x

    @property
    def x(self):
        return self.__x

class Bar:
    def __new__(cls, *args, **kwargs):
        foo = super().__new__(Foo)
        foo.__init__(*args, **kwargs)
        return foo

bar = Bar(10)
print(bar.x)

  

看一個返回自身類實例的:rem

class Bar:
    def __new__(cls, *args, **kwargs):
        foo = super().__new__(cls)
        return foo

    def __init__(self, x):
        self.__x = x

    @property
    def x(self):
        return self.__x

bar = Bar(10)
print(bar.x)

  

二.__new__的一些用途

大多數狀況下都不須要重寫__new__。it

1.單例模式:

class Foo:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super().__new__(cls)
        return cls.__instance

foo1 = Foo()
foo2 = Foo()
print(foo1, foo2)

  

輸出:
<__main__.Foo object at 0x0000029A4B879048> <__main__.Foo object at 0x0000029A4B879048>
能夠看出foo1和foo2是同一個實例class

2.限制實例的建立數量:

class Foo:
    __instance = []
    limit = 2
    def __new__(cls, *args, **kwargs):
        print(len(cls.__instance))
        if len(cls.__instance) == cls.limit:
            raise RuntimeError("Count not create instance. Limit %s reached" % cls.limit)
        instance = super().__new__(cls)
        cls.__instance.append(instance)
        return instance

    def __del__(self):
        self.__instance.remove(self)

foo1 = Foo()
foo2 = Foo()
print(foo1, foo2)

  

3.自定義實例建立

您能夠自定義建立的實例,並在調用初始化程序__init__以前對其進行一些操做。此外,您能夠基於某些約束對實例建立施加限制object

def is_create():
    #根據條件判斷是否能夠建立
    return True

class Foo:
    def __new__(cls, a, b):
        if not is_create():
            raise RuntimeError('實例不能被建立')
        instance = super().__new__(cls)
        instance.count = a + b
        return instance

    def __init__(self, a, b):
        pass

foo = Foo(1, 2)
print(foo.count)

  

4.自定義返回的對象

一般,當您實例化類時,它將返回該類的實例。您能夠自定義此行爲,而且能夠返回所需的對象。程序

class Foo:
    def __new__(cls, a, b):
        instance = super().__new__(cls)
        instance.__init__(a, b)
        return a + b
    def __init__(self, a, b):
        print('a+b')


foo = Foo(1, 2)
print(foo)

  

若是咱們不從__new__方法返回實例對象,則必須顯式調用__init__。方法

相關文章
相關標籤/搜索