python实现单例模式的常用三种方法-基于__new__/使用装饰器以及Python中的值类型、引用类型以及类的静态变量、读取进程和线程ID

一、python实现单例模式的常用三种方法-基于__new__,使用装饰器

        涉及到类的使用就会有类的实例化,就会有类单例实现的需求,因为重复实例化会浪费资源。python中的单例模式与别的语言相比,单例实现的方法更丰富。虽然python实现单例的模式的方法有很多,不过在体验后我觉得有必要了解和掌握的也就是使用模块和使用装饰器两种,然后了解一下使用__new__方法实现单例。

1. 使用python模块

        Python模块本身就包含了一个单例实现逻辑,在第一次导入时,会生成.pyc文件,之后导入,就会直接加载.pyc,因此如果在我们在模块中new实例对象,然后在其它的地方直接引用生成的对象,就是单例模式了,python模块singleton.py内容如下:

#模块中的方法
class Singleton(object):def test(self):print("test")#直接初始化类	
singleton = Singleton()

在其它的地方使用时,直接导入此文件中的对象即是单例模式的对象
from singleton import singleton

2. 使用__new__方法

        因为python实例化对象的逻辑是先执行类的__new__方法(默认调用object.__new__)实例化对象,再执行类的__init__方法对这个对象进行初始化,所有我们可以在__new__方法中进行控制以实现单例模式,代码示例如下:

class Singleton(object):def __init__(self):passdef __new__(cls, *args, **kwargs):if not hasattr(Singleton, "_instance"):if not hasattr(Singleton, "_instance"):Singleton._instance = object.__new__(cls)  return Singleton._instance

3. 使用装饰器实现单例模式

        上面的使用__new__方法需要在每个类中去定义方法体,而使用装饰器则可以实现定义一个方法体,然后装饰给所有我们要实现单例模式的类即可,重复利用并简化代码。推荐使用第3种方法.

#定义一个单例方法
def Singleton(cls):_instance = {}def _singleton(*args, **kargs):if cls not in _instance:_instance[cls] = cls(*args, **kargs)return _instance[cls]return _singleton#装饰给所有我们要实现单例模式的类即可
@Singleton
class Test(object):def test_fun(self):pass

        关于线程安全的单例模式,上述第2、3种方法能实现单例模式,但并不是线程安全的单例模式,如果有需求实现线程安全,可以进行改造,添加threading模块并进行加锁控制。示例如下。

# 使用__new__方法创建基于线程安全的单例模式
import threading
class Singleton(object):_instance_lock = threading.Lock()def __init__(self):passdef __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# 使用__new__方法创建基于线程安全的单例模式	
import threading
def Singleton(cls):_instance = {}lock = threading.Lock()def _singleton(*args, **kargs):with lock:if cls not in _instance:_instance[cls] = cls(*args, **kargs)return _instance[cls]return _singleton#装饰给所有我们要实现单例模式的类即可
@Singleton
class Test(object):def test_fun(self):pass

        关于多线程模块,thread模块已被废弃,在Python3中不能再使用thread模块。用户可以使用threading模块代替。

二、Python中的值类型、引用类型以及类的-静态-变量

        Python中的数据类型分为值类型和引用类型,值类型通常包含int、float、bool、str、tuple,值类型是不可变的。引用类型包含list、set、dict类型,引用类型是可变的。在python的面向对象中,类不存在像其它语言中存在的static关键词,因此不能使用修饰实现类的静态变量。python面向对象中只有实例变量和类变量两变量概念,根本不存在静态变量的概念。

        接下来我们来看下面这个例子以及其运行结果,结果中有横线来区分开每个执行结果,比较好分别,如下:

#定义四个方法,各操作一些属性
class task1:value=1def increment(self):self.value += 1class task2:value=[]def increment(self):self.value.append(1)class task3:def __init__(self):self.value=[]def increment(self):self.value.append(1)class task4:value=1def increment(self):self.value += 1#分别调用四个方法	
if __name__=="__main__":a=task1()b=task1()a.increment()print(a.value)print(b.value)print('-'*30)a=task2()b=task2()a.increment()print(a.value)print(b.value)print('-'*30)a=task3()b=task3()a.increment()print(a.value)print(b.value)print('-'*30)print('-'*30)a=task4()b=task4()task4.value+=1print(a.value)print(b.value)a.increment()print(a.value)print(b.value)print(task4.value)

程序运行结果如下:

===========运行结果=================
2
1
------------------------------
[1]
[1]
------------------------------
[1]
[]
------------------------------
2
2
3
2
2

第1个示例应该如我们预期,只改变了a而b的没有变更。
第2个示例和第1个基本相同,但结果却是a和b都同时发生了改变。
第3个示例在2示例上做了一些改变,从而符合我们的预期。
第4个示例我们改变了task4的属性,其它的类的属性有的有影响,有的却没有影响。
是为什么呢?
    第1个和第2个示例的相同点是都是类的属性,但一个是值类型,一个是引用类型。引用类型的类变量就如同我们其它语言的静态变量,尽管python没有静态变量的概念,但这样操作就实现了静态变量的功能。第3个示例和第2个的区别是第3个用的是实例的变量,所以各自归各自管理。第4个示例,实例化a和b的时候,他们都没有对属性value进行操作,所以打印出来的都是类task4的属性value,而在对象对自己的value进行操作之后,就与类的属性脱离关系,变成自己的属性。 

三、Python中读取程序中的进程和线程ID

    程序调试的时候有时需要看看当前程序的进程和线程ID,可以使用如下的方法。

#引入OS和psutil库
import os
import psutil
import threading#取得python进程数据
pid = os.getpid()
p = psutil.Process(pid)
print('PID: %d' % pid)
print('PNAME: %s' % p.name())
print(p.__dict__)#取得线程ID数据
t = threading.currentThread()
print("TID: %d" % t.ident)
print("TID: %d" % t.name)
print("TNAME: %S" % t.getName())
print(t.__dict__)#print(p)打印出来的结果
psutil.Process(pid=14572, name='python.exe', status='running', started='18:46:27')
#print(p.__dict__)打印出来的结果格式化之后
{'_pid': 15144,'_name': 'python.exe','_exe': None,'_create_time': 1629788019.0382779,'_gone': False,'_hash': None,'_lock': < unlocked _thread.RLock object owner = 0 count = 0 at 0x0000020F41511840 > ,'_ppid': None,'_proc': < psutil._pswindows.Process object at 0x0000020F416E4700 > ,'_last_sys_cpu_times': None,'_last_proc_cpu_times': None,'_exitcode': < object object at 0x0000020F41BAE470 > ,'_ident': (15144, 1629788019.0382779)
}#print(t)打印出来的结果
<_MainThread(MainThread, started 15280)>
#print(t.__dict__)打印出来的结果格式化之后
{'_target': None,'_name': 'MainThread','_args': (),'_kwargs': {},'_daemonic': False,'_ident': 7652,'_native_id': 7652,'_tstate_lock': < locked _thread.lock object at 0x000002A0A834AA20 > ,'_started': < threading.Event object at 0x000002A0A834A7F0 > ,'_is_stopped': False,'_initialized': True,'_stderr': < _io.TextIOWrapper name = '<stderr>'mode = 'w'encoding = 'gbk' > ,'_invoke_excepthook': < function _make_invoke_excepthook. < locals > .invoke_excepthook at 0x000002A0A8352CA0 >
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/439015.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文掌握Harbor镜像同步公有云镜像仓库实践

一文掌握Harbor镜像同步公有云镜像仓库实践 目录 1 引言2 概念 2.1 Harbor2.2 阿里云的镜像仓库ACR2.3 华为云的镜像仓库SWR2.4 Harbor复制管理同步镜像 2.4.1 复制管理的工作原理 2.5 Harbor同步镜像到公有云镜像仓库的优势 3 实验&#xff1a;通过Harbor 将容器镜像同步到公…

win7怎么禁用驱动强制数字签名?win7驱动程序强制数字签名禁用方法

在Windows 7 64位操作系统中&#xff0c;安装驱动程序时可能会遇到“数字签名”的问题&#xff0c;这是微软为了确保驱动程序的安全性和可靠性而引入的一项安全机制。本文将深入探讨这个问题&#xff0c;并提供有效的解决方案。 理解数字签名的概念是至关重要的。数字签名是一…

C语言复习概要(二)

本文目录 C语言中的数组与函数详解1. 引言2. 数组2.1. 什么是数组&#xff1f;语法&#xff1a;示例&#xff1a; 2.2. 数组的初始化示例 1&#xff1a;在声明时初始化示例 2&#xff1a;部分初始化示例 3&#xff1a;运行时赋值 2.3. 数组的访问与修改示例&#xff1a; 2.4. 多…

【Python游戏开发】贪吃蛇游戏demo

准备步骤 项目开发使用【Mu 编辑器】 1.新建项目&#xff0c;并导入游戏图片 游戏编写 1.创建场景 SIZE 15 # 每个格子的大小 WIDTH SIZE * 30 # 游戏场景总宽度 HEIGHT SIZE * 30 # 游戏场景总高度def draw():screen…

LabVIEW裂纹深度在线监测系统

随着铁路运输技术的快速发展&#xff0c;火车安全问题成为重中之重&#xff0c;尤其是轮面裂纹的检测和管理。裂纹的出现可能导致严重的列车事故&#xff0c;因此&#xff0c;建立可靠的在线监测系统&#xff0c;实时掌握裂纹情况&#xff0c;对保障铁路运输安全至关重要。 La…

在线JSON可视化工具--支持缩放

先前文章提到的超好用的JSON可视化工具&#xff0c;收到反馈&#xff0c;觉得工具好用&#xff0c;唯一不足就是不能缩放视图&#xff0c;其实是支持的&#xff0c;因为滚轮有可能是往下滚动&#xff0c;会与缩放冲突&#xff0c;所以这个工具设计为需要双击视图来触发打开缩放…

选择网络安全模式启动Windows系统,解决PC无法连接网络问题

目录 1、电脑无法连接网络 2、发现C:\Windows\System32\drivers路径下的很多文件不见了 3、使用360安全卫士中的断网急救箱工具修复&#xff0c;也就解决不了问题 4、重启系统&#xff0c;以网络安全模式启动系统&#xff0c;修复系统网络模块&#xff0c;完美解决问题 5、…

AI不可尽信

看到某项目有类似这样的一段代码 leaves : make([]int, 10) leaves leaves[:0]没理解这样的连续两行,有何作用? 初始化一个长度和容量都为10的切片,接着把切片长度设置为0 即如下demo: (在线地址) package mainimport "fmt"func main() {leaves : make([]int, 1…

加密与安全_HOTP一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

智能视界·大模型驱动视频矩阵管理系统

开头先配两张ER图 一张不带字段&#xff0c;一张带字段&#xff0c;剩下的内容按需拿取 1.产品介绍 产品名称&#xff1a; 智能视界大模型驱动视频矩阵管理系统 主要功能&#xff1a; 智能视频分析与识别 功能介绍&#xff1a;该系统集成先进的人工智能大模型&#xff0c;能…

Sping源码:三级缓存

目录 一、概念1、三级缓存的作用2、循环依赖的含义 二、代码1、代码下载2、文件功能介绍3、源码分析3.1、找到获取A对象的位置&#xff0c;打断点进行debug操作3.2、一步步找到在A对象中注入B对象的位置3.3、一步步找到B对象注入A对象的位置3.4、往下找到通过三级缓存解决循环依…

车辆重识别(2020NIPS去噪扩散概率模型)论文阅读2024/9/27

[2] Denoising Diffusion Probabilistic Models 作者&#xff1a;Jonathan Ho Ajay Jain Pieter Abbeel 单位&#xff1a;加州大学伯克利分校 摘要&#xff1a; 我们提出了高质量的图像合成结果使用扩散概率模型&#xff0c;一类潜变量模型从非平衡热力学的考虑启发。我们的最…

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是最常用的协议之一&#xff0c;广泛应用于各种网络应用&#xff0c;如网页浏览、文件传输和在线游戏等。然而&#xff0c;随着互联网的普及&#xff0c;小数据包的频繁传输成为一个不容忽视的问题。…

智能手表(Smart Watch)项目

文章目录 前言一、智能手表&#xff08;Smart Watch&#xff09;简介二、系统组成三、软件框架四、IAP_F411 App4.1 MDK工程结构4.2 设计思路 五、Smart Watch App5.1 MDK工程结构5.2 片上外设5.3 板载驱动BSP5.4 硬件访问机制-HWDataAccess5.4.1 LVGL仿真和MDK工程的互相移植5…

malloc源码分析之 ----- 你想要啥chunk

文章目录 malloc源码分析之 ----- 你想要啥chunktcachefastbinsmall binunsorted binbin处理top malloc源码分析之 ----- 你想要啥chunk tcache malloc源码&#xff0c;这里以glibc-2.29为例&#xff1a; void * __libc_malloc (size_t bytes) {mstate ar_ptr;void *victim;vo…

【PHP陪玩系统源码】游戏陪玩系统app,陪玩小程序优势

陪玩系统开发运营级别陪玩成品搭建 支持二开源码交付&#xff0c;游戏开黑陪玩系统: 多客陪玩系统&#xff0c;游戏开黑陪玩&#xff0c;线下搭子&#xff0c;开黑陪玩系统 前端uniapp后端php&#xff0c;数据库MySQL 1、长时间的陪玩APP源码开发经验&#xff0c;始终坚持从客户…

CentOS 替换 yum源 经验分享

视频教程在bilibili:CentOS 替换 yum源 经验分享_哔哩哔哩_bilibili问题原因 解决方法 1. 进入镜像目录 [rootlocalhost ~]# cd /etc/yum.repos.d/ 2.备份文件 [rootlocalhost yum.repos.d]# rename repo bak * 3.寻找阿里镜像源复制 https://developer.aliyun.com/mirror/ …

【pytorch】张量求导4

再再接上文&#xff0c;看到作者有一个关于向量乘矩阵的描述。 经过搜索发现&#xff0c;现在的pytorch已经修复了这一问题&#xff0c;提供了mv()和matmul()两种方式实现矩阵和一维向量的乘积&#xff0c;可以参看这篇文章。 经过查阅pytorch的文件&#xff0c;找到了cuda侧…

【重学 MySQL】五十三、MySQL数据类型概述和字符集设置

【重学 MySQL】五十三、MySQL数据类型概述和字符集设置 MySQL数据类型概述MySQL字符集设置注意事项 MySQL数据类型概述 MySQL是一个流行的关系型数据库管理系统&#xff0c;它支持多种数据类型&#xff0c;以满足不同数据处理和存储的需求。理解并正确使用这些数据类型对于提高…

SpringBoot整合异步任务执行

同步任务&#xff1a; 同步任务是在单线程中按顺序执行&#xff0c;每次只有一个任务在执行&#xff0c;不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务&#xff0c;无法同时处理多个任务&#xff0c;响应慢&#xff0c;影响…