网上有很多文章描述,我只是做一些笔记。
__new__是类的方法,在创建对象之前调用,__init__是对象的方法,在创建对象之后调用。如下代码:
class A(object):
def __init__(self, name):
print("init:%s" % name)
print(self)
def __new__(cls, name):
print("new:%s" % name)
res = super(A, cls).__new__(cls, name)
print(res)
return res
if __name__ == '__main__':
a = A('haha')
print(a)
其输出为:
new:haha
<__main__.A object at 0x7f8923c236d0>
init:haha
<__main__.A object at 0x7f8923c236d0>
<__main__.A object at 0x7f8923c236d0>
__new__带来了很多好处,官方说法是用于继承一些不可变的基本类型,举例如下:
class MyInt(int):
def __init__(self, val):
super(MyInt, self).__init__(self, -val)
class MyInt2(int):
def __new__(cls, val):
return super(MyInt2, cls).__new__(cls, -val)
class MyStr(str):
def __init__(self, val):
super(MyStr, self).__init__(self, 'prefix' + val)
class MyStr2(str):
def __new__(cls, val):
return super(MyStr2, cls).__new__(cls, 'prefix' + val)
if __name__ == '__main__':
a = MyInt(100)
print(a)
b = MyInt2(100)
print(b)
c = MyStr('abc')
print(c)
d = MyStr2('abc')
print(d)
输出为:
100
-100
abc
prefixabc
可见python里的基本类型创建对象之后,就不能再改变了。__new__能够在创建之前完成必要的计算。不过实际中,很少会有继承基本类型的需求。
__new__带来更多的好处是便于实现各种设计模式。比如单例模式:
class Singleton(object):
def __new__(cls):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
if __name__ == '__main__':
a = Singleton()
print(a)
b = Singleton()
print(b)
因为__new__可以返回任何类型的对象,再比如工厂模式:
class Car(object):
pass
class Truck(object):
pass
class Train(object):
pass
class Vehicle(object):
def __new__(cls, name):
if name == 'Car':
return Car()
elif name == 'Truck':
return Truck()
elif name == 'Train':
return Train()
if __name__ == '__main__':
a = Vehicle('Car')
print(a)
b = Vehicle('Truck')
print(b)
c = Vehicle('Train')
print(c)
总之,__new__用来在类型上塞meta data,而__init__用来在实例上塞member data。