pyhton中的__new__和__init__

首先__new__() 函数只能用于从object继承的新式类;其次,object将__new__()方法定义为静态方法,并且至少需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。

下面,看一个关于__init__和__new__的例子:

class Person(object):
    def __new__(cls, name, age):
        print('%s:__new__ called.' %name)
        return super(Person, cls).__new__(cls)

    def __init__(self, name, age):
        self.name=name
        self.age = age
        print('%s:__init__ called.' %name)

    def __str__(self):
        return self.name
    
if __name__ == '__main__':
    ming = Person('ming', 24)
    print(ming)

执行结果:

ming:__new__ called.
ming:__init__ called.
ming

通过运行这段代码,我们可以看到,__new__方法的调用是发生在__init__之前的。

总结:

  1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
  2.__new__ 通常用于控制生成一个新实例的过程。它是类级别的方法。
那么,我们一般什么时候会用到__new__方法呢?

1、当我们在继承一些不可变的类时(比如int, str, tuple),我们可以通过这个方法自定义这些不可变类的实例化过程。

我们用int类来举例:

  假如我们需要一个永远都是正数的整数类型,可以通过继承int类,然后可能会写出这样的代码:

class PositiveInteger(int):
    def __init__(self, value):
        super(PositiveInteger, self).__init__(self, abs(value))
 
i = PositiveInteger(-3)
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

2、可以用__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)   #value1 value1
print(obj1 is obj2) #True

可以看出obj1和obj2是同一个实例。

原文地址:https://www.cnblogs.com/value-code/p/8546520.html