用python实现单例模式_Python单例模式的两种实现方式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
在 Python 中,我们可以用多种方法来实现单例模式
1.使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
解释一下这个装饰器:单例模式的主要目的就是确保某一个类最多只能有一个实例存在,换句话说某一个类只能和它的一个实例有联系,所以字典这种键值对型的容器非常适合单例模式这种情况。如果某个类不在字典里,那么在字典里创建一个键为某个类(cls),值为该类创建的实例(cls(*args, **kwargs))这样的一个键值对。如果某个类已经在字典里,那么说明这个类在之前已经创建过实例了,按照单例模式一个类最多只能有一个实例的思想,那么直接返回该类的实例
2.基于__new__方法实现
当我们实现单例时,为了保证线程安全需要在内部加入锁
我们知道,当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.new),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式
import threading
class Singleton(object):
_instance_lock = threading.Lock()
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = object.__new__(cls)
return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)
def task(arg):
obj = Singleton()
print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start()
简单一点,没有加锁的方式:
#使用__new__方法在创造实例时进行干预,达到实现单例模式的目的
#这里使用了_instance属性来存放实例
class Singleton: #一个通用的单例超类,其他类继承即可(也可通过装饰器实现)
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls)
return cls._instance
class SingleSpam(Singleton):
def __init__(self, s):
self.s = s
def __str__(self):
return self.s
s1 = SingleSpam('spam')
print(id(s1), s1)
s2 = SingleSpam('spa')
print(id(s2), s2)
介绍一下__new__:
class A:
pass
class B(A):
def __new__(cls):
print("__new__方法被执行")
return super().__new__(cls)
def __init__(self):
print("__init__方法被执行")
b = B()
# __new__方法被执行
# __init__方法被执行
我们比较两个方法的参数,可以发现__new__方法是传入类(cls),而__init__方法传入类的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象(如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法)。我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,而__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作。
用python实现单例模式_Python单例模式的两种实现方式相关推荐
- 多线程python实现方式_python多线程的两种实现方式(代码教程)
本篇文章给大家带来的内容是关于python多线程的两种实现方式(代码教程),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 线程是轻量级的进程,进程中可划分出多个线程,线程可独立的调度 ...
- python请输入_python中的三种输入方式
python中的三种输入方式 python2.X python2.x中以下三个函数都支持: raw_input() input() sys.stdin.readline() raw_input( )将 ...
- 【无标题】单例模式的两种创建方式:饿汉式和懒汉式
这里写自定义目录标题 单例模式的两种创建方式:饿汉式和懒汉式 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂 ...
- python定义字符串变量有两种常用方式_Python 1基础语法二(标识符、关键字、变量和字符串)...
一.标识符 标识符就是程序员自己命名的变量名.名字需要有见名知义的效果,不要随意起名 :比如 a=1 a是个变量,a这个变量名属于标识符 1 company = '小米 2 employeeNum = ...
- python字典对象的方法返回字典的值列表_python对象转字典的两种实现方式示例
本文实例讲述了python对象转字典的两种实现方式.分享给大家供大家参考,具体如下: 一. 方便但不完美的__dict__ 对象转字典用到的方法为__dict__. 比如对象对象a的属性a.name= ...
- 简单介绍python连接telnet和ssh的两种方式
本文主要介绍了python连接telnet和ssh的两种方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 Telnet 连接方式 #!/usr/bin/env p ...
- python 读取wav 音频文件的两种方式
python 中,常用的有两种可以读取wav音频格式的方法,如下所示: 1 import scipy 2 from scipy.io import wavfile 3 4 import soundfi ...
- python repair修复功能_详解Python修复遥感影像条带的两种方式
GDAL修复Landsat ETM+影像条带 Landsat7 ETM+卫星影像由于卫星传感器故障,导致此后获取的影像出现了条带.如下图所示, 影像中均匀的布满条带. 使用GDAL修复影像条带的代码如 ...
- python支持的编程方式包括,python的两种编程方式是什么
一.交互式编程 什么是交互式编程,就是在命令行中输入python 命令即可启动交互式编程,提示窗口如下: 而且还用了Python3的print方法打印出一串字符串. 二.脚本式编程 通过脚本参数调用解 ...
- Python操作Neo4j图数据库的两种方式
Python操作Neo4j图数据库的两种方式 前言 1. 用neo4j模块执行CQL ( cypher ) 语句 2. 用py2neo模块通过操作python变量,达到操作neo4j的目的 3. 用p ...
最新文章
- c语言语系的命名风格和java系命名风格
- 围巾都这么黑科技了,是我见识少了
- 成功解决FileNotFoundError: [WinError 2] 系统找不到指定的文件。
- MySQl的一些基本知识(1)
- 明日之后怎么跳过实名认证_明日之后宝箱达人活动怎么玩 明日之后宝箱达人可以开箱多少次...
- 一个高并发的测试websocket脚本
- tensorrt安装_基于TensorRT的BERT推断加速与服务部署
- ASA8.4端口映射篇
- Android 震动
- 求字符串中对称的子字符串的最大长度
- Cogs 647. [Youdao2010] 有道搜索框(Trie树)
- 中国氮化镓(GaN)行业“十四五”前景预测及投资风险预测报告2021年版
- usbcan、can分析仪的产品特点和功能特点
- Discuz 手动添加 markdown 代码支持教程!
- html代码 层次选择器,CSS样式类的实例代码(导航栏、分页、层级选择器)
- css flex实现经典的三栏布局
- APS究竟是什么系统呢?看完文章你就知道了
- 《大唐卫星网络电视》
- 中国马铃薯全粉产业经营策略与销售渠道研究报告(2022-2027年)
- python基础语法25_Python基础语法习题参考(0-9关)