python单例模式应用之pymongo连接

文章目录

    • 单例模式介绍
    • 模块简介
    • 安装
    • 简单的连接使用
    • 单例模式的连接
      • 单例类的实现
      • 配置的使用
      • 单例模式的测试
    • 单例连接的调用

https://gitee.com/allen-huang/python

单例模式介绍

适用场景:
单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:

  1. 需要频繁实例化然后销毁的对象。
  2. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  3. 有状态的工具类对象。
  4. 频繁访问数据库或文件的对象。

以下都是单例模式的经典使用场景:

  1. 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。还有windows系统的回收站和任务管理器,只能打开一个。
  2. 控制资源的情况下,方便资源之间的互相通信。多线程的线程池的设计一般就是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

接下来就是以 pymongo模块的来举例说明

模块简介

pymongo 是 python 操作 mongodb 的官方库,它pymongo 提供了mongdb和python交互的所有方法,文档地址:https://www.mongodb.com/docs/drivers/pymongo/

安装

pip install pymongo

简单的连接使用

先使用常规的连接方式来创建 pymongo 的连接看下,下面展示的是一个测试用例代码,具体源码在 gitee 上
源码的具体链接:https://gitee.com/allen-huang/python/blob/master/python-code/do-mongodb/test_client.py

  • 方式1:
...
def test_client1(self):"""简单连接1@return:"""# 创建连接client = MongoClient(host="127.0.0.1", port=27017, username="admin", password="YrnKzEubSv6")# 选择一个库下面的集合,如果集合不存在,则自动新建coll = client['test']['user']print(coll.find_one({'uid': 1}))pass
...

在这里插入图片描述

  • 方式2:
...
def test_client2(self):"""简单连接方式2:使用连接字符串@return:"""# 创建连接uri = f"mongodb://admin:YrnKzEubSv6@127.0.0.1:27017/?maxPoolSize=20"client = MongoClient(uri, connectTimeoutMS=5000)# 选择一个库下面的集合,如果集合不存在,则自动新建coll = client['test']['user']print(coll.find_one({'uid': 1}))pass
...

在这里插入图片描述

单例模式的连接

这里创建单例模式,是基于__new__方法结合 pymongo的连接池来实现,pymongo 的连接池是内部已经集成了的,只要设置 maxPoolSize 参数就行。

单例类的实现

import threading
from pymongo import MongoClient
from conf.load_config import Configclass MongoPool(object):"""mongodb连接池创建"""_pool = None_instance = None_lock = threading.Lock()  # 线程锁,是属于同步锁def __new__(cls):if not cls._instance:  # 在并发进来的时候,只会创建一次,如果已经创建了,就不用排队再去等待上锁了再判断实例是否为空,这样子可以提高性能。with cls._lock:  # 类似JAVA的synchronized,自动获取和释放锁if not cls._instance:cls._instance = cls.get_pool()return cls._instance@classmethoddef get_pool(cls):"""获取连接池实例"""user = Config['mongodb']['user']host = Config['mongodb']['host']port = Config['mongodb']['port']password = Config['mongodb']['password']maxPoolSize = Config['mongodb']['maxPoolSize']connectTimeoutMS = Config['mongodb']['connectTimeoutMS']# 连接mongodb的URIuri = f"mongodb://{user}:{password}@{host}:{port}/?maxPoolSize={maxPoolSize}"client = MongoClient(uri, connectTimeoutMS=connectTimeoutMS)return client

配置的使用

  • 配置的格式:

是基于 yaml 来的,根据不同服务器环境变量来 自动匹配配置文件,pyYaml的使用参考这一篇文章。

安装:

pip install pyyaml
  • 环境变量来控制不同的配置

可以根据服务器各自的环境变量 来匹配(开发、测试、生产环境)的配置文件,这样子的好处就是各自的环境配置都不受到影响,提高的系统的稳定
我这边测试的是mac本地,在.zshrc文件中,环境变量共用了之前 chatgpt 项目设置好的环境变量 CHATGPT_PYTHON_ENV,在测试和生产环境的原理也一样,只需要改成CHATGPT_PYTHON_ENV="test"CHATGPT_PYTHON_ENV="prod"就行。

在这里插入图片描述

  • 配置加载代码

源码的链接地址:https://gitee.com/allen-huang/python/tree/master/conf/load_config.py

import os
from os.path import abspath, dirnameimport yaml# 获取各个环境对应的配置文件
CONFIG_FILES = {'dev': 'config-dev.yaml','test': 'config-test.yaml','prod': 'config-prod.yaml'
}# 获取配置
Config = {}def load_config():global Config# 获取当前运行环境env = os.getenv('CHATGPT_PYTHON_ENV', 'dev')if env not in CONFIG_FILES:raise ValueError('没有该环境的配置文件')with open(abspath(dirname(__file__)) + '/' + CONFIG_FILES[env], 'r', encoding='utf-8') as f:try:Config = yaml.safe_load(f)except yaml.YAMLError as e:raise e# 读取当前项目的运行环境,如果没有则默认是dev环境
try:load_config()
except Exception as e:print(e)

单例模式的测试

开启10个线程测试, 这里不采用单元测试,而是采用__main__里面执行线程,因为单元测试使用多线程会有问题,线程执行不全。
源码地址:https://gitee.com/allen-huang/python/blob/master/python-code/do-mongodb/test_client_singleton.py

import threading
import timefrom db.mongo_pool import MongoPooldef task(arg):mongo_obj = MongoPool()# 连接池对象是否是同一个地址str = f"执行编号:{arg}, 连接对象的内存地址: {id(mongo_obj)}"# 等待2秒time.sleep(2)print(str)# 使用多线程进行测试
if __name__ == '__main__':thread_list = []for i in range(10):t = threading.Thread(target=task, args=(i,))thread_list.append(t)t.start()for t in thread_list:t.join()

在这里插入图片描述

单例连接的调用

下面是测试用例的代码,具体源码看链接https://gitee.com/allen-huang/python/blob/master/python-code/do-mongodb/test_client.py

...
def test_client3(self):"""简单连接方式3:使用单例@return:"""data = MongoPool().test.user.find_one({'uid': 1})print(data)
...

在这里插入图片描述

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

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

相关文章

第二十二周周报

论文研读:Camera Distance-aware Top-down Approach for 3D Multi-person Pose Estimation from a Single RGB Image 粗读10篇文献。 通过图2 我可以知道这个论文大概实现的这个姿态估计效果的方法,首先是把图片输入到DetectNet网络,该网络…

面具安装LSP模块时提示 Unzip error错误的解决办法

面具(Magisk Delta)安装LSP模块时提示 Unzip error错误的解决办法 ​​ 如果前面的配置都正常的话,可能是LSP版本有问题重新去Github下载一个最新版的吧;我是这么解决的。 我安装1.91那个版本的LSP就是死活安装不上,下载了1.92的版本一次就…

OpenGrok代码服务器搭建,解决代码检索慢的问题

一、背景 在前一家公司,公司提供了OpenGrok服务器供大家检索查阅代码。但在新公司,大家都使用vscode或Sourse Insight,这就存在一些问题: 不能跳转或者跳转比较慢。 搜索查询速度慢,且结果展示不易查看。 这严重影…

给 spyter/all-spark-notebook 添加scala支持

spyter/all-spark-notebook默认没有安装scala notebook,需要手动添加。 你可以创建一个新的 Dockerfile,在其中添加你需要的配置和组件。以下是一个简单的例子: FROM jupyter/all-spark-notebook:x86_64-ubuntu-22.04 #冒号后可以是latest&a…

OpenHarmony教程指南-性能示例

介绍 本示例集成了条件渲染、动态加载以及HiDumper等场景来介绍如何提升应用性能。 效果预览 HiDumper使用说明: 1.点击性能示例主页的HiDumper按钮,进入HiDumper查看组件信息场景页。 1.点击HiDumper查看组件信息场景页的查看应用组件树进入场景页。…

10个高级的 SQL 查询技巧

1.常见表表达式(CTEs) 如果您想要查询子查询,那就是CTEs施展身手的时候 - CTEs基本上创建了一个临时表。 使用常用表表达式(CTEs)是模块化和分解代码的好方法,与您将文章分解为几个段落的方式相同。 请在…

YOLOv8原创二次改进DCNv3结构:即插即用|使用纯pytorch代码实现,不需要CUDA编译,并针对YOLOv8专门优化模块,基于可变形卷积的超强变种

💡本篇内容:YOLOv8原创改进DCNv3结构:即插即用|使用纯pytorch代码实现,不需要CUDA编译,并针对YOLOv8专门优化模块,基于可变形卷积的超强变种,优势:不需要编译! 💡附改进源代码及教程,用来改进🚀 DCNv3可变形网络结构 VisDrone有效涨点 关键词:DCNv3网络改进…

Linux智能网关结合Node-RED实现实时工业数据采集

工业4.0的发展,物联网技术在制造业中的应用越来越广泛。其中,基于Linux系统的工业物联网智能网关因其开放性、稳定性和安全性而备受青睐。这类智能网关创新性地集成了开源工具Node-RED,为从各种工业设备(如PLC)中高效收…

Mysql日志总结

Undo log 概念:undo log 是一种用于撤销回退的日志。在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。 版本链:当前记录 undo log 作用&#xf…

沁恒蓝牙芯片CH582:蓝牙OTA升级技术详解与应用探索

文章目录 一、前言1.WCH 蓝牙空中升级(BLE OTA)概述2. WCH BLE SDK DFU 工作原理(方式一) 二、移植程序1.找到BackUpgrade_OTA例程2.添加文件到工程2.1 添加文件2.2 如何添加 3.修改APP工程3.1 修改peripheral_main.c文件3.2 修改…

代码随想录刷题笔记 DAY 42 | 最后一块石头的重量 II No.1049 | 目标和 No.494 | 一和零 No.474

文章目录 Day 4301. 最后一块石头的重量 II&#xff08;No. 1049&#xff09;<1> 题目<2> 笔记<3> 代码 02. 目标和&#xff08;No. 494&#xff09;<1> 题目<2> 笔记<3> 代码 03. 一和零&#xff08;No. 474&#xff09;<1> 题目&l…

Unity 采用自定义通道ShaderGraph实现FullScreen的窗户雨滴效果

效果如下 ShaderGraph实现 N21 随机化 DragLayer分层 将DragLayer分成四层&#xff0c;分别调整每层的缩放和大小 Shader实现的链接&#xff08;Unity 雨水滴到屏幕效果&#xff09; 我也是参考这个实现Shader Graph