- 单例模式介绍
- 实现单例模式的第一种方式
- 实现单例模式的第二种方式
- 实现单例模式的第三种方式
- 实现单例模式的第四种方式
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
单例模式介绍
什么是单例模式 |
---|
单例模式:多次实例化的结果指向同一个实例
是面向对象的一种设计模式
举例 |
---|
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
# 第一次实例化
obj1=MySQL('1.1.1.1',3306)
# 再一次实例化,又得到一个容器
obj2=MySQL('1.1.1.1',3306)
# 第三次实例化
obj3=MySQL('1.1.1.1',3306)
## 我们经过三次实例化会发现,会产生3个内存地址,这三个内存地址存储的数据都是一样的,所以我们没有必要存储那么多次。
## 所以单例模式的作用,就是把结果指向一个实例,如此一来,我们就可以做到节省资源
## 例如我们之前实现 过的,使用settings.py文件来存储数据,然后导入
### settings.py
IP='1.1.1.1'
PORT=3306
### 导入settings.py文件
import settings
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1=MySQL(settings.IP, settings.PORT)
obj2=MySQL(settings.IP, settings.PORT)
obj3=MySQL(settings.IP, settings.PORT)
实现单例模式的第一种方式
代码语言:javascript复制import settings
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls):
return cls(settings.IP,settings.PORT)
obj1=MySQL.from_conf()
obj2=MySQL.from_conf()
obj3=MySQL.from_conf()
print(obj1)
print(obj2)
print(obj3)
# 比原来精简了,但是没有实现单例
import settings
class MySQL:
__instance=None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls):
if cls.__instance is None:
cls.__instance=cls(settings.IP, settings.PORT)
return cls.__instance
obj1=MySQL.from_conf()
obj2=MySQL.from_conf()
obj3=MySQL.from_conf()
obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第二种方式
使用装饰器来实现
代码语言:javascript复制import settings
def singleton(cls):
def wrapper(*args,**kwargs):
instance=cls(*args,**kwargs)
return instance
return wrapper
@singleton #MySQL=singleton(MySQL) #MySQL=wrapper
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj=MySQL('1.1.1.1',3306) #obj=wrapper('1.1.1.1',3306)
print(obj.__dict__)
## 目前装饰器 ,什么功能都没有实现,我们要定制,MySQL内不传递任何参数就返回已经定义好的对象
import settings
def singleton(cls):
_instance=cls(settings.IP,settings.PORT)
def wrapper(*args,**kwargs):
if len(args) !=0 or len(kwargs) !=0:
obj=cls(*args,**kwargs)
return obj
return _instance
return wrapper
@singleton #MySQL=singleton(MySQL) #MySQL=wrapper
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1=MySQL() #wrapper()
obj2=MySQL() #wrapper()
obj3=MySQL() #wrapper()
obj4=MySQL('1.1.1.3',3302) #wrapper('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第三种方式
使用元类来实现单例模式
代码语言:javascript复制import settings
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
#self=MySQL这个类
self.__instance=self(settings.IP,settings.PORT)
def __call__(self, *args, **kwargs):
# self=MySQL这个类
if len(args) != 0 or len(kwargs) != 0:
obj=self.__new__(self)
self.__init__(obj,*args, **kwargs)
return obj
else:
return self.__instance
class MySQL(metaclass=Mymeta): #MySQL=Mymeta(...)
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj1=MySQL()
obj2=MySQL()
obj3=MySQL()
obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第四种方式
使用导入模块的方式
settings.py
代码语言:javascript复制IP='1.1.1.1'
PORT=3306
singleton.py
代码语言:javascript复制import settings
class MySQL:
print('run....')
def __init__(self, ip, port):
self.ip = ip
self.port = port
instance=MySQL(settings.IP,settings.PORT)
导入singleton模块并调用
代码语言:javascript复制def f1():
from singleton import instance
print(instance)
def f2():
from singleton import instance,MySQL
print(instance)
obj=MySQL('1.1.1.3',3302)
print(obj)
f1()
f2()