首先__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是同一个实例。