title: Python单例模式
tags: Python
单例模式就是对象只实例化一次,再次实例化还是原来实例化的。单例模式的创建一共有三种方式:
1 模块导入的方式
导入的模块中有实例化的对象,该对象就是单例模式。仅在模块导入的时候实例化一次,之后就可以使用该对象。
如CRM中v1.py中实例化的site。site = CurdSite() # 实例化对象,就是self 这里就是单例模式
2 实例化先执行函数的方式
class Foo:
_instance = None
def __init__(self): # 2 实例化对象
pass
@classmethod
def get_instance(cls):
if cls._instance:
return cls._instance # 4 再次执行函数的时候执行,返回的仍然是obj
else:
obj = cls() # 1 下面执行的时候先执行这里,然后执行__init__
cls._instance = obj # 3 对类属性_instance赋值
return obj
f1 = Foo.get_instance()
f2 = Foo.get_instance()
print(f1)
print(f2)
结果:
__main__.Foo object at 0x0000000002ACB5F8
__main__.Foo object at 0x0000000002ACB5F8
在单例模式中的__init__中传参数并调用参数
class Foo:
_instance = None
def __init__(self,name): # 2 实例化对象
self.name = name # 传入参数
@classmethod
def get_instance(cls,*args,**kwargs): # 接收参数
if cls._instance:
return cls._instance # 4 再次执行函数的时候执行,返回的仍然是obj
else:
obj = cls(*args,**kwargs) # 1 下面执行的时候先执行这里,然后执行__init__
cls._instance = obj # 3 对类属性_instance赋值
return obj
f1 = Foo.get_instance("asdfasdf") # 实例化对象
f2 = Foo.get_instance("zds")
print(f1.name) # 执行对象的方法
print(f2.name)
最终结果得到的是一样的内容:
asdfasdf
asdfasdf
<__main__.Foo object at 0x000000000280B7B8>
<__main__.Foo object at 0x000000000280B7B8>
3 __new__
的方式
上面的方式调用的时候和普通的实例化不一致,通过__new__改造成与普通实例化一致的方式
__new__是创建实例的方法,__init__是类创建实例后调用,所以__new__先执行
class Foo:
_instance = None
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if cls._instance:
return cls._instance
else:
# obj = super().__new__(cls,*args,**kwargs)
obj = object.__new__(cls, *args, **kwargs) # 所有的类都是object创建的
cls._instance = obj
return obj
f1 = Foo()
f2 = Foo()
print(f1)
print(f2)