python中实例创建过程离不开两个函数__init__() 和 __new__(),__new__()负责创建instance(实例),而__init__()负责customize(个性化定制,或者称为初始化 -- 其他语言中称呼),然后返回给caller(调用者),即完成实例创建。有一个比喻特别适合这两个角色的工作: 我们生活中房子建造过程就如同python中实例创建,楼看作类,具体到某个楼就是实例。
下面讲讲这两个函数:
1. __new__(cls):
new方法是一个静态方法,无论加不加@staticmethod装饰器他都是静态方法
new函数是在创建实例时被调用,功能:创建实例,创建实例时调用的是父类或者超类的__new__(cls)方法,其中自动传入创建实例的类,返回一个实例对象,然后调用__init__()方法来customize,如果__new__(cls)返回的不是一个cls的实例则不会调用__init__()方法,由于这种设计就产生一种单例模式实现方式(通过重写__new__()方法实现)
注意: 如果自己重写了new方法,且调用了自己的__new__(cls)方法将会导致无限递归,死循环
例如(死循环例子):
class Test:
def __new__(cls, *args, **kwargs):
return cls.__new__(cls)
正确写法:
class Test:
def __new__(cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs) # 加入参数是放置父类中new需要参数情况,不加*args, **kwargs也不没问题
# 借此我们就可以通过重写__new__()方法来实现单例模式
借此我们就可以通过重写__new__()方法来实现单例模式
class Test:
__obj = None
def __new__(cls, *args, **kwargs):
if cls.__obj is None:
cls.__obj = super().__new__(cls) # 利用父类创建实例
return cls.__obj
2. __init__(self, *args, **kwargs):
__new__方法下存放是实例变量, 作用初始化实例变量。
new方法创建实例后由__new__()方法来customize(new方法把它接收到的*args, **kwargs参数传递个__init__方法)
3. 单例模式案例补充:
(1) 通过静态方法或者类方法实现
class Test:
__obj = None
@staticmethod
def get_instance(*args, **kwargs): 实例化时需要加的参数
if Test.__obj is None:
Test.__obj = Test(*args, **kwargs)
return Test.__obj
(2) 通过装饰器实现
def singleton(cls): # cls为类
dic = dict()
def inner(*args, **kwargs): # 这里加参数是因为有可能类创建时传入参数了,所以这里需要加(根据装饰器原理,真正调用的是inner方法,然后inner返回实例)
if cls not in dic:
dic[cls] = cls(*args, **kwargs)
return dic[cls]
return inner
@singleton # 加上装饰器即可实现
class T:
pass
(3). 通过类方法方法实现
class TestOne:
__obj = None
@classmethod
def get_instance(cls, *args, **kwargs):
if cls.__obj is None:
cls.__obj = cls(*args, **kwargs)
print(cls)
return cls.__obj
tt = TestOne.get_instance()
tt1 = TestOne.get_instance()
print(id(tt), id(tt1)) # 判断是否为同一个实例
我就讲这些了,如果有什么问题或者心得可以一块讨论学习,也请大家批评指正