python__new__
使用 类名() 创建对象时,python首先会调用__new__方法为对象分配空间。
如果__new__()没有返回cls(即当前类)的实例,那么当前类的__init__()方法是不会被调用 的。
class Foo():
def __new__(cls, *args, **kwargs):# 不return则不会执行初始化方法
print("调用__new__方法")
return super().__new__(cls) # 必须返回对象的引用
def __init__(self, *args, **kwargs):
print("调用__init__方法")
foo = Foo()
print(foo)
print (type(foo))
打印结果:
调用__new__方法
调用__init__方法
<__main__.Foo object at 0x00000182A65959B0>
<class '__main__.Foo'>
- 重写 _new_ 方法 一定要 return super()._new_(cls)
- 否则 Python 的解释器 得不到分配了空间的 对象引用,就不会调用对象的初始化方法
- 注意:_new_ 是一个静态方法,在调用时需要 主动传递 cls 参数
- cls:当前正在实例化的类。 如果要得到当前类的实例,应当在当前类中的__new__()方法语句中调用当前类的父类
的__new__()方法。
例如,如果当前类是直接继承自object,那当前类的__new__()方法返回的对象应该为:
def __new__(cls, *args, **kwargs):
...
return object.__new__(cls)
注意:
- Python默认是调用该类的直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写 _new_(),那么将一直按此规矩追溯至object的__new__()方法,因为object是所有新式类的基类。
- 而如果新式类中重写了__new__()方法,那么你可以自由选择任意一个的其他的新式类*(必定要是
新式类,只有新式类必定都有__new__(),因为所有新式类都是object的后代,而经典类则没有__new__() 方法)的__new__()方法来制造实例,包括这个新式类的所有前代类和后代类,只要它们不会造成递归死 循环。 - 在任何新式类的__new__()方法,不能调用自身的__new__()来制造实例,因为这会造成死循环。因此必须避免类似以下的写法:在Foo中避免:
return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)
使用object或者没有血缘关系的新式类的__new__()是安全的,但是如果是在有继承关系的两个类之间,应避免互调造成死循环.
示例:
class Foo():
def __new__(cls, *args, **kwargs):
return object.__new__(Stranger)
def __init__(self, *args, **kwargs):
pass
class Stranger(object):
pass
foo = Foo()
print(foo)
print (type(foo))
结果:
<__main__.Stranger object at 0x000001A267706940>
<class '__main__.Stranger'>
python单例模式
# 单例模式
class Single(object):
__obj = None
__init_flag = True
# 实现只实例化对象一次
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
cls.__obj = object.__new__(cls)
return cls.__obj
# 初始化对象
# def __init__(self):
# print("实例化")
# 初始化一次
def __init__(self):
if Single.__init_flag:
print("实例化")
Single.__init_flag = False
a = Single()
b = Single()
print(a)
print(b)