单例模式
单例模式:5种方法
实例:连接数据库时,防止每次操作都去创建数据库连接,所以使用单例模式仅在第一次使用时,创建连接,以后均使用该连接即可
4种方法:
a. 基于文件导入实现单例模式(pycheml自带的方式)
b. 基于 classmethod
c. 基于 __new__
d. 基于 metaclass
e. 基于 装饰器
a. 基于文件导入实现单例模式(pycheml自带的方式)
import func1
import func1
# 单例模式 所以只导入一次
import importlib
importlib.reload(func1) # 可以重新再导入一次模块
b. 基于 classmethod
1 class Foo(object): 2 def __init__(self): 3 self.name = 'alex' 4 @classmethod 5 def get_instance(cls,*args,**kwargs): 6 if not hasattr(cls,'instend'): 7 print('====lalal') 8 obj = cls(*args,**kwargs) 9 cls.instend = obj 10 return cls.instend 11 f1 = Foo.get_instance() 12 f2 = Foo.get_instance() 13 print(f1,f2)
#<__main__.Foo object at 0x000000000295CFD0> <__main__.Foo object at 0x000000000295CFD0>
c. 基于 __new__
class Foo(object): instance = None def __init__(self): self.a = 1 def __new__(cls, *args, **kwargs): if not cls.instance: obj = super().__new__(cls, *args, **kwargs) cls.instance = obj return cls.instance print(Foo()) print(Foo())
d. 基于 metaclass
class Mytype(type): def __call__(self, *args, **kwargs): obj = self.__new__(self,*args,**kwargs) if not hasattr(self,'instance'): print(self,'<<<') self.instance = obj return self.instance class Foo(metaclass=Mytype): def __init__(self,a): self.a = a print(Foo('alex')) print(Foo('aaa')) print(Foo('bbb'))
e. 基于装饰器
def singletonde(func):
instance = {}
def wrapper(*args, **kwargs):
if func.__name__ not in instance:
instance[func.__name__] = func(*args, **kwargs)
return instance[func.__name__]
return wrapper
@singletonde
class Singleton:
def __init__(self, name):
self.name = name
a = Singleton('aaa')
b = Singleton('bbb')
print(a, a.name)
print(b, b.name)