前记
__new__用来创建实例,在返回的实例上执行__init__,如果不返回实例,则__init__不执行;
__new__方法:
__new__方法是在类准备将自身实例化时调用;
__new__方法始终是类的静态方法;
__new__的第一个占位参数是class对象,__init__的第一个占位参数是class的实例对象,其他的参数一致;
__init__用来初始化实例,设置属性等;
一、__init__方法
示例:
class Person(object):
def __init__(self,name,age):
print("__init__ is called.")
self.name = name
self.age = age
def __str__(self):
return "<Person:%s(%s)>"%(self.name,self.age)if __name__ == '__main__':
test = Person("test",24)
print(test)
输出:
__init__ is called.
<Person:test(24)>
结论:初始化类实例;
二、__new__方法
示例:
class Person(object):
def __new__(cls,name,age):
print('__new__ called.')
return super(Person,cls).__new__(cls)def __init__(self, name, age):
print('__init__ called.')
self.name = name
self.age = agedef __str__(self):
return '<Person: %s(%s)>' % (self.name, self.age)if __name__ == '__main__':
test = Person('test',24)
print(test)
输出:
__new__ called.
__init__ called.
<Person: test(24)>
结论:
p=Person(name,age)步骤,先使用name、age参数执行Person类的__new__方法,返回一个Person类的实例(使用super(Person,cls).__new__(cls,...)方式),然后利用这个实例调用类的__init__方法。
三、__new__的作用
当继承一些不可变的class时(int、str、tuple),提供一个自定义这个类实例化的途径。
如,需要一个永远时正数的整数类型,通过继承int;
示例1:
import mathclass PositiveInteger(int):
def __init__(self, value):
super(PositiveInteger, self).__init__()i = PositiveInteger(-100)
print(i)
输出:
-100
实例2:
class PositiveInteger(int):
def __new__(cls, value):
return super(PositiveInteger, cls).__new__(cls, abs(value))i = PositiveInteger(-100)
print(i)
输出:
100结论:重载__new__实现功能;
四、用__new__实现单例(singleton)
类的每一次实例化过程通过__new__控制,重载__new__可实现单例模式;
class Singleton(object):
def __new__(cls):
if not hasattr(cls,"instance"):
cls.instance = super(Singleton,cls).__new__(cls)
return cls.instanceobj1 = Singleton()
obj2 = Singleton()obj1.attr1="value1"
print(obj1.attr1)
print(obj2.attr1)
print(obj1)
print(obj2)
输出:
value1
value1
<__main__.Singleton object at 0x000001ED462879B0>
<__main__.Singleton object at 0x000001ED462879B0>
结论:obj1和obj2是用一个实例,即单实例。
注:如有错误,请指正!