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__。方法

相关文章
相关标签/搜索