【Python】Python 利用模块实现单例模式
Python 利用模块实现单例模式
在GOF的23种设计模式中,单例是最常使用的模式,通过单例模式可以保证系统中 一个类只有一个实例而且该实例易于被外界访问,从而方便对实例个数的控制并节约系统资 源。每当大家想要实现一个名为XxxMangcr的类时,往往意味着这是一个单例。在游戏编程 中尤是如此,比如一个名为World的单例管理着游戏中的所有资源,包括一个名为Sun的单 例,它给这个世界带来了光亮。
单例如此常见,所以有不少现代编程语言将其加到了语言特性中,如scala和falcon语 言都把object定义成关键同,并用其声明单例。如在scala中,—个单例如下:
object Singleton{
def show = println(“I am a singleton”)
}
object定义了一个名为Singleton的单例,它满足单例的3个需求:一是只能有一个实 例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例3对于第三点. 在任何地方都可以通过调用Singleton.show()来验证。在scala中,单例没有显式的初始化操 作.但并不是所有在语法层面支持单例模式的编程语言都如此,比如falcon就不一样。
object object_name [ from classl, class2 … classN]
property__l = expression
property_2 = expression
…
property_N = expression
[init block]
function method_l( [parameter_list])
[method_body]
end
function method_N(lparameter_list])
[method_body]
end
end
上面是falcon语言的单例语法,[init block]能够让程序员手动控制单例的初始化代码。但是与scala和falcon相比,动态语言Python就没有那么方便了,主要原因是Python缺乏声 明私有构造函数的语法元素,实例又带有类型信息。比如以下方法是不可行的:
class _Singleton(object):
pass
Singleton = _Singleton()
del _Singleton # 试图刪除 class 定义
another = Singleton.class() # 没用,绕过!
print(type(another))
#输出
<class ‘main._Singleton’>
可见虽然把Singleton的类定义删除了,但仍然有办法通过己有实例的__class__属性生成一个新的实例。于是许多Pythonista把目光聚集到真正创建实例的方法__new__上,并做起了文章。
class Singleton(object):
_instance = None
def new(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super (Singleton, cls).new(cls,*args,**kwargs)
return cls._instance
if name ==“mian”:
s1=Singleton()
s2=Singleton()
assert id(s1) == id(s2)
这个方法很好地解决了前面的问题,现在基本上可以保证“只能有一个实例”的要求了, 但是在并发情况下可能会发生意。为了解决这个问题,引入一个带锁的版本。
import threading
class Singleton(object):
objs =()
objs_locker = threading.Lock()
def new(cls, *args, **kv):
if cls in cls.objs:
return cls.objs[cls]
cls.objs_locker.acquire()
try:
if cls in cls.objs: ## double check locking
return cls.objs[cls]
cls.objs[cls] = object.new(cls)
finally:
cls.objs_locker.release()
利用经典的双检査锁机制,确保了在并发环境下Singleton的正确实现。但这个方案并 不完美,至少还有以下两个问题:
如果Singleton的子类重载了 new()方法,会覆盖或者干扰Singleton类中__new__()的执行,虽然这种情况出现的概率极小,但不可忽视。
如果子类有__init__()方法,那么每次实例化该Singleton的时候,init()都会被调 用到,这显然是不应该的,init()只应该在创建实例的时候被调用一次。
这两个问题当然可以解决,比如通过文档告知其他程序员,子类化Singleton的时候, 请务必记得调用父类的__new__()方法;而第二个问题也可以通过偷偷地替换掉方 法来确保它只调用一次。但是,为了实现一个单例,做大量的、水面之下的工作让人感觉相 当不Pythonic。这也引起了 Python社区的反思,有人开始重新审视Python的语法元素,发 现模块采用的其实是天然的单例的实现方式。
所有的变量都会绑定到模块。
模块只初始化一次。
import机制是线程安全的(保证了在并发状态下模块也只有一个实例)。
当我们想要实现一个游戏世界时,只需简单地创建World.py就可以了。
World.py
import Sun
def run():
while True:
Sun.rise()
Sun.set()
然后在人口文件main.py里导入,并调用run()函数,看,是不是感觉这种方式最为 Pythonic 呢?
main.py
import World
World.run()
Alex Martelli认为单例模式要求“实例的唯一性”本身是有问题的,实际更值得关注 的是实例的状态,只要所有的实例共享状态(可以狭义地理解为属性)、行为(可以狭 义地理解为方法)一致就可以了。在这一思想的进一步指导下,他提出了 Borg模式 在C#中又称为Monostate模式)。
class Borg:
_shared_state = {}
def init(self):
self.diet = self.__shared_stateand whatever else you want in your class – that’s all!
通过Borg模式,可以创建任意数量的实例,但因为它们共享状态.从而保证了行为一致。虽然Alex的这个Borg模式仅适用于古典类(classic clasess), Python 2.2版本 以后的新式类(new-style classes)需要使用__getattr__和__setattr__方法来实现(代码略),但其可开阔眼界。
相关文章:
【Python】Python 利用模块实现单例模式
Python 利用模块实现单例模式 在GOF的23种设计模式中,单例是最常使用的模式,通过单例模式可以保证系统中 一个类只有一个实例而且该实例易于被外界访问,从而方便对实例个数的控制并节约系统资 源。每当大家想要实现一个名为XxxMangcr的类时&…...
雅思写作 三小时浓缩学习顾家北 笔记总结(四)
目录 The company should provide maternity leave and other assistance to female employees with children. Community redevelopment provides opportunities for offenders to acquire vocational skills. The law should classify drunk driving as a criminal offens…...
深入学习与探索:高级数据结构与复杂算法
文章目录 学习高级数据结构B树:数据库引擎的骨干线段树:高效的区间查询Trie树:高效的字符串检索 探索复杂算法领域图算法:解决复杂网络问题字符串匹配算法:处理文本搜索近似算法:在NP难题上取得近似解 结论…...
CV:计算机视觉CV运用领域
计算机视觉是一项涉及大量算法和技术的跨学科领域,已经在众多领域得到广泛的应用。以下是计算机视觉的一些主要应用领域: 图像处理和图像分析:计算机视觉技术可以用于图像处理和图像分析,识别和检测特定的图像特征,例如…...
开源机密计算平台:蓬莱-OpenHarmony
演讲嘉宾 | 杜 东 回顾整理 | 廖 涛 排版校对 | 李萍萍 嘉宾简介 杜东,上海交通大学助理研究员。中国计算机学会CCF会员,ACM会员。研究兴趣为操作系统与体系结构、服务器无感知(Serverless)计算、系统安全。在包括ASPLOS、ISC…...
大一大二一心学算法的利弊
学习算法是现代计算机科学和软件工程领域中的重要组成部分。它们是解决复杂问题、优化资源利用以及提高效率的关键。学习算法的过程可以帮助培养系统性思维、分析问题能力和创造性解决方案的能力。然而,学习算法也有一些利弊,我们将在下文中详细探讨。 …...
c#using关键字的作用
https://blog.csdn.net/Mona_Zhao/article/details/91363446 using关键字的三种作用: 1. 引用命名空间; 2. 为命名空间或者类型创建别名; 3. 使用using语句。 (1)引用命名空间 类似于c和c的#include<>, pyt…...
只依赖OPENCV的工作服安全帽检测YOLOV8S
工地安全帽工作服检测Y8S,采用YOLOV8S训练模型,然后使用OPENCV的DNN调用,彻底拜托PYTORCH依赖,可以在C,PYTHON,ANDROID上跑。附件是C生成的效果测试(只需解压将图片或者视频放入VIDEOS文件夹,文件夹没图片或…...
MFC|选择获取文件路径
参考:mfc按钮选择文件或者文件夹(https://blog.csdn.net/qq_39433050/article/details/130261518) 点击按钮槽函数,选择文件 void CMFCStartGrabDlg::OnBnClickedSelectfile() {// TODO: Add your control notification handler…...
实时操作系统Freertos开坑学习笔记:(七):队列
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、队列是什么?而在freertos中,队列是什么呢?①如果要进行中断、任务的交流,那我用全局变量行吗?②…...
专业游戏翻译公司怎么选择比较合适
近年来,游戏行业持续繁荣,市场需求也在不断扩大,其中游戏翻译的需求越来越旺盛。无论是引进游戏还是让游戏走向国际市场,都需要专业的翻译公司来帮忙。那么,怎么选择合适的游戏翻译公司呢?让我们一起来看看…...
阿里云Maven和Gradle仓库最新配置
文章目录 一、简介二、仓库地址三、如何配置1、Maven配置2、Gradle配置 一、简介 阿里云云效 Maven 是什么? 阿里云Maven中央仓库为 阿里云云效 提供的公共代理仓库,帮助研发人员提高研发生产效率,使用阿里云Maven中央仓库作为下载源&am…...
尚硅谷大数据项目《在线教育之离线数仓》笔记007
视频地址:尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 第12章 报表数据导出 P112 01、创建数据表 02、修改datax的jar包 03、ads_traffic_stats_by_source.json文件 P113 P114 P115 P116 P117 P118 P119 P120 P121 P122【122_在…...
python考研志愿填报模拟系统vue
本系统提供给管理员对学生、院校、研究生信息、专业信息、学院信息等诸多功能进行管理。本系统对于学生输入的任何信息都进行了一定的验证,为管理员操作提高了效率,也使其数据安全性得到了保障。本考研志愿填报模拟系统以Django作为框架,B/S模…...
【LeetCode-面试经典150题-day20】
目录 70.爬楼梯 198.打家劫舍 139.单词拆分 322.零钱兑换 300.最长递增子序列 70.爬楼梯 题意: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 提示: 1 < n < …...
回归与聚类算法系列②:线性回归
目录 1、定义与公式 2、应用场景 3、特征与目标的关系分析 线性回归的损失函数 为什么需要损失函数 损失函数 ⭐如何减少损失 4、优化算法 正规方程 梯度下降 优化动态图 偏导 正规方程和梯度下降比较 5、优化方法GD、SGD、SAG 6、⭐线性回归API 7、实例&#…...
springBoot:redis使用
需求:查询酒店房间列表 1、引入依赖 <!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 2、配置yml文件 server:port: 80…...
cmake 选择 vs编译器
QQ:2967732156 QQ交流群:622684416 // 编译VS2017版本的Tars, Release版本 // win32 cmake .. -G "Visual Studio 15 2017" -D CMAKE_BUILD_TYPERelease // x64 cmake .. -G "Visual Studio 15 2017 Win64" -D CMAKE_BUILD_…...
项目(智慧教室)第一部分:cubemx配置,工程文件的移植,触摸屏的检测,项目bug说明
第一章:需求与配置 一。项目需求 二。实现外设控制 注意: 先配置引脚,再配置外设。否则会出现一些不可预料的问题 1.时钟,串口,灯,蜂鸣器配置 (1)RCC配置为外部时钟,修…...
Springboot集成redis--不同环境切换
1.单机配置 spring:redis:mode: singletonhost: 127.0.0.1port: 6379lettuce:pool:max-active: 8 #连接池最大阻塞等待时间(使用负值表示没有限制max-idle: 2 #连接池中的最大空闲连接min-idle: 1 #连接池最大阻塞等待时间(使用负值表示没有限…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
