单例模式
单例模式:指的是在确定 “类中的属性与方法” 不变时,需要反复调用该类,产生不同的对象,而产生的对象会有不同的内存地址,会造成资源浪费,所有让所有的类实例化时都指向同一个内存空间,称为单例模式
优点:节省内存空间
单例模式有五种方法实现:
- 通过classmethod
- 通过装饰器实现
- 通过__ new__实现
- 通过导入模块实现
- 通过元类实现
1、通过classmethod
# 通过classmethod
class MySQL:
# 一个默认值,用于判断对象是否存在, 对象不存在证明值是None
# __instance是类的属性,可以由类来调用
__instance = None # ---》 执行到代码obj = cls(host, port) ---》 obj
# __instance = obj
def __init__(self, host, port):
self.host = host
self.port = port
@classmethod
def singleton(cls, host, port): # 单例方法 ---》 类方法
# 判断__instance中若没有值,证明没有对象
if not cls.__instance:
# 产生一个对象并返回
obj = cls(host, port)
# None ---> obj
cls.__instance = obj
# 若__instance中有值,证明对象已经存在,则直接返回该对象
return cls.__instance
def start_mysql(self):
print('启动mysql')
def close(self):
print('关闭mysql')
obj1 = MySQL.singleton('180.101.49.12', 443)
print(obj1) # <__main__.MySQL object at 0x00000207EFC09188>
obj2 = MySQL.singleton('180.101.49.12', 443)
print(obj2) # <__main__.MySQL object at 0x00000207EFC09188>
class Mysql:
__date = None
def __init__(self, name):
self.name = name
@classmethod
def func(cls, name):
if not cls.__date:
obj = cls(name)
cls.__date = obj
return cls.__date
obj1= Mysql.func('sean')
obj2= Mysql.func('sean')
print(obj1)
print(obj2)
class Mysql:
__date = None
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
if not cls.__date:
obj = object.__new__(cls)
cls.__date = obj
return cls.__date
obj1= Mysql('sean')
obj2= Mysql('sean')
print(obj1)
print(obj2)
'''
输出结果
<__main__.Mysql object at 0x0000013E2DEBC208>
<__main__.Mysql object at 0x0000013E2DEBC208>
<__main__.Mysql object at 0x0000013E2E2B9C08>
<__main__.Mysql object at 0x0000013E2E2B9C08>
'''
方式二: __new__
class Singleton2:
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
obj1 = Singleton2()
obj2 = Singleton2()
print(obj1)
print(obj2)
方式三: 装饰器
def singleton(cls): # cls---> Father
_instance = {}
def inner(*args, **kwargs):
if cls not in _instance:
obj = cls(*args, **kwargs)
_instance[cls] = obj
return _instance[cls]
return inner
@singleton
class Father:
pass
print(Father())
print(Father())
类可以当做字典的key
print({Father: 111})
方式四: 模块导入
# 先写一个singleton模块
class SingletonCls:
pass
obj = SingletonCls()
# 在另一个文件写
from Singleton import obj
print(obj)
from Singleton import obj
print(obj)
from Singleton import obj
print(obj)