当前位置: 首页 > news >正文

全局数据在Python包中模块间管理方法探讨

在开发大型 Python 应用程序时,有时需要多个模块共享和管理全局数据。如何优雅地在 Python 包内的不同模块间共享全局数据是一个常见的设计问题。我们希望避免全局变量的混乱和难以维护的代码,但同时能够安全、高效地管理这些共享数据。

下面我们将探讨几种常用的全局数据管理方法,以及如何在模块间合理共享和修改全局数据。

在这里插入图片描述

1、问题背景

在Python或其他编程语言中,如何管理跨包的模块中全局数据?在设计语言Heron的包和模块系统时,我受Python模块系统启发很大。Python有丰富的模块选择,这似乎对其成功有很大贡献。其中存在疑问的是,如果在一个Python模块中包含了两个不同的已编译包,会发生什么情况:是制作数据副本还是共享数据?与此相关的是一系列侧问题:

我假设包在Python中可以被编译,是否正确?

模块数据复制或共享的两种方法有什么优缺点?

从Python社区的角度来看,Python的模块系统存在哪些众所周知的问吗?例如,是否有正在考虑用于增强模块/包的PEP?

Python模块/包系统中哪些方面对编译语言来说行不通?

2、解决方案

回答1:

a. Python代码被词法分析并编译成Python特定指令,但没有被编译成机器可执行代码。".pyc"文件会在运行与现有.pyc时间戳不匹配的Python代码时自动创建。可以关闭此功能。可以使用dis模块来查看这些指令。
b. 导入模块时,它将在其命名空间中(从上到下)执行,并将该命名空间全局缓存。从另一个模块导入时,该模块不会再次执行。请记住,def只是一个语句。可能需要在代码中放置一个print(‘compiling this module’)语句来跟踪它。

这取决于具体情况。
最近有一些增强,主要围绕指定需要加载哪些模块。模块可以有相对路径,以便一个大项目中有多个具有相同名称的模块。
Python本身不能用于编译语言。在Google中搜索“unladen swallow blog”,查看试图加速语言的磨难。“a = sum(b)”在执行之间可以改变含义。撇开极端情况,模块系统在源代码和编译库系统之间形成了一个很好的桥梁。这种方法很有效,Python轻松地封装C代码(swig等)有所帮助。

示例.py:
print “Creating %s module.” % name

def show_def(f):
print “Creating function %s.%s.” % (name, f.name)
return f

@show_def
def a():
print “called: %s.a” % name

交互式会话:

import example

先检查sys.modules[‘example’]

由于它不存在,可以找到example.py并将它“编译”到example.pyc

(由于example.pyc不存在,如果它是过时的,也会发生同样的情况,等等)

Creating example example module. # 执行模块代码
Creating function example.a. # 执行def语句

example.a()
called: example.a
import example

找到sys.modules[‘example’],将局部变量example分配给该对象

没有 ‘Creating …’ 输出

d = {“name”: “fake”}
exec open(“example.py”) in d

本次会话中的第一次导入与此非常相似

它创建一个模块对象(具有__dict__),初始化其中的几个变量

builtins, name__和其他变量—包的__init

模块也有自己的变量—查看some_module.dict.keys()或

dir(some_module))

并执行example.py中的代码(或存储在example.pyc中的代码对象)

Creating fake module. # 执行模块代码
Creating function fake.a. # 执行def语句

d.keys()
[‘builtins’, ‘name’, ‘a’, ‘show_def’]
d’a’
called: fake.a

解答2:
模块是Python中唯一真正的全局对象,所有其他全局数据都基于模块系统(它使用sys.modules作为注册表)。包只是具有导入子模块的特殊语义的模块。“在某种意义上讲,编译”一个.py文件成.pyc或.pyo并不是大多数语言所了解的编译:它只检查语法并创建一个在解释器中执行时创建模块对象的代码对象。

示例.py:
print “Creating %s module.” % name

def show_def(f):
print “Creating function %s.%s.” % (name, f.name)
return f

@show_def
def a():
print “called: %s.a” % name

交互式会话:

import example

先检查sys.modules[‘example’]

由于它不存在,可以找到example.py并将它“编译”到example.pyc

(由于example.pyc不存在,如果它是过时的,也会发生同样的情况,等等)

Creating example example module. # 执行模块代码
Creating function example.a. # 执行def语句

example.a()
called: example.a
import example

找到sys.modules[‘example’],将局部变量example分配给该对象

没有 ‘Creating …’ 输出

d = {“name”: “fake”}
exec open(“example.py”) in d

本次会话中的第一次导入与此非常相似

它创建一个模块对象(具有__dict__),初始化其中的几个变量

builtins, name__和其他变量—包的__init

模块也有自己的变量—查看some_module.dict.keys()或

dir(some_module))

并执行example.py中的代码(或存储在example.pyc中的代码对象)

Creating fake module. # 执行模块代码
Creating function fake.a. # 执行def语句

d.keys()
[‘builtins’, ‘name’, ‘a’, ‘show_def’]
d’a’
called: fake.a

你的问题:

它们在某种意义上是编译的,但如果你熟悉C编译器的工作方式,那么它们与你的预期不符。
如果数据是不可变的,那么复制是可行的,除了对象标识符(Python中的is运算符和id())外,它与共享应该是无法区分的。

导入可能会或可能不会执行代码(它们总是会将局部变量分配给一个对象,但这不会产生问题),并且可能会或可能不会修改sys.modules。必须小心不要在多线程中导入,通常最好在每个模块的顶部进行所有导入:这将导致一个级联图,以便立即完成所有导入,然后__main__继续并执行真正的任务。

我不知道当前是否有任何PEP,但已经有很多复杂的机制到位。例如,包可以具有__path__属性(实际上是一个路径列表),因此子模块不必位于同一目录中,这些路径甚至可以在运行时计算!(请看下面的mungepath包示例。)你可以拥有自己的导入挂钩,在函数中使用import语句,直接调用__import__,而且我不会感到惊讶会找到2-3其他独特的方法来使用包和模块。

导入系统的一个子集可以在传统编译语言中使用,只要它类似于C的#include即可。可以在编译器中运行“第一级”执行(创建模块对象),并编译那些结果。然而,这样做有显着的缺点,等于模块级代码和运行时执行的函数的分离执行上下文(有些函数必须在这两个上下文中运行!)。(请记住在Python中每条语句都在运行时执行,即使是def和class语句也是如此。)

我认为这是传统编译语言将“顶层”代码限制为类、函数和对象声明、消除第二个上下文的主要原因。即使在那时,你也会遇到C/C++(和其他语言)中全局对象的初始化问题,除非小心地管理。

mungepath/init.py:
print path
path.append(“.”) # CWD,在非示例代码中会不同
print path
from . import example # 这是上面示例的example.py,不在mungepath/中

注意这是一个退化的情况,因为现在我们用两个名称来表示

“相同”的模块:example和mungepath.example,但它们实际上是

具有不同函数的不同模块(使用 ‘is’ 或 ‘id()’ 来验证)

交互式会话:

import example
Creating example module.
Creating function example.a.
example.dict.keys()
[‘a’, ‘builtins’, ‘file’, ‘show_def’, ‘package’,
name’, ‘doc’]
import mungepath
[‘mungepath’]
[‘mungepath’, ‘.’]
Creating mungepath.example module.
Creating function mungepath.example.a.
mungepath.example.a()
called: mungepath.example.a
example is mungepath.example
False
example.a is mungepath.example.a
False

解答3:
全局数据在解释器级别进行控制。

“包”可以被编译,因为包只是可以编译的模块的集合。
我不确定我在给定数据确定的作用域下理解。

在 Python 包中管理全局数据的方法有多种,具体选择取决于应用的规模和需求:

  1. 简单项目:可以使用专门的模块存储全局数据,适用于全局数据较少且简单的情况。
  2. 面向对象项目:使用单例模式是一个更优雅的选择,尤其在需要数据封装时。
  3. 多线程/异步项目contextvars 提供了线程安全的全局数据管理方法。
  4. 结构化数据:使用 dataclasses 或配置对象可以提供更强的数据结构化管理。
  5. 跨进程:环境变量适合用于跨进程或容器化应用。

根据项目的需求和复杂度,选择合适的全局数据管理方法能够提高代码的可维护性和可扩展性。

相关文章:

全局数据在Python包中模块间管理方法探讨

在开发大型 Python 应用程序时,有时需要多个模块共享和管理全局数据。如何优雅地在 Python 包内的不同模块间共享全局数据是一个常见的设计问题。我们希望避免全局变量的混乱和难以维护的代码,但同时能够安全、高效地管理这些共享数据。 下面我们将探讨…...

无人机在矿业领域的应用!

矿区测绘与建模 无人机可以快速、全面地获取矿区的地形地貌数据,生成高精度的二维或三维模型。 这些模型可用于矿区的规划、设计、监测和管理,提高矿山的生产效率。 库存量量化监测 无人机能够捕捉厘米级的地形数据,通过计算得出准确的库…...

基于JavaWeb开发的java springmvc+mybatis学生考试系统设计和实现

基于JavaWeb开发的java springmvcmybatis学生考试系统设计和实现 🍅 作者主页 网顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各…...

【CKA】四、etcd的备份与恢复

4、etcd的备份与恢复 1. 考题内容: 2. 答题思路: 1、ssh到有etcdctl、etcdutl命令的节点 2、备份时注意添加证书并保证路径正确 3、备份完可以验证下 4、恢复备份时要停服务,恢复备份后重启kubelet 题型是一样的,我考的证书的路…...

基于Arduino的SG90舵机驱动

一.SG90舵机引脚说明 SG90舵机三根线的连接方法: 1.红色线:电源线(VCC),接入5v电源 2.棕色线:地线(GND),接地 3.黄色线:信号线(SIG)…...

大模型泡沫破了?| 转行建筑师混战大模型圈

最近秋招惨淡卷动,**地产天坑不敢进,科技大厂不可期。**阿里直裁应届生、腾讯拉长职级晋升时间,字节一家繁荣,但也在和美国政府大打官司。此前「大模型」风生水起,但近期融资、应用双双预冷。 GPT-5迟迟不出&#xff0…...

Windows开发工具使用技巧

Windows开发工具使用技巧 在Windows系统下进行软件开发时,掌握并熟练使用合适的开发工具可以极大地提高工作效率和代码质量。本篇文章将介绍几款常见的Windows开发工具及其使用技巧,涵盖集成开发环境(IDE)、命令行工具、版本控制…...

【PyTorch学习-1】张量操作|自动求导|神经网络模块|优化器|数据加载与处理|GPU 加速...

【PyTorch学习-1】张量操作|自动求导|神经网络模块|优化器|数据加载与处理|GPU 加速… 【PyTorch学习-1】张量操作|自动求导|神经网络模块|优化器|数据加载与处理|GPU 加速… 文章目录 【PyTorch学习-1】张量操作|自动求导|神经网络模块|优化器|数据加载与处理|GPU 加速...前言…...

Leecode热题100-560.和为k的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums [1,1,1], k 2 输出:2示例 2: 输入:nums [1,2,3], k…...

Mac 卸载 IDEA 流程

1、现在应用程序中删除Idea 2、进入Library目录 cd /Users/zhengzhaoxiang/Library 3、删除IntelliJIdea2023.3(根据自己的版本而定)记得进去看下是否删除干净了 rm -rf Logs/JetBrains/IntelliJIdea2023.3 rm -rf Preferences/com.jetbrains.intel…...

vue3 antdv3/4 Modal显示一个提示,内容换行显示。

1、官网地址: Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 2、显示个信息: Modal.info({title: This is a notification message,content: h(div, {}, [h(p, some messages...some messages...),h(p, some …...

Jgit的使用

Jgit的使用 文章目录 Jgit的使用一,git操作的对应代码1.1 查看操作1.1.1 打开仓库1.1.3 获取状态信息 1.2 添加操作1.2.1 初始化本地仓库1.2.2 创建一个新文件并写入内容1.2.3 添加指定(所有)文件到暂存区1.2.4 提交操作1.2.5 连接并推送到远…...

SQL Server—约束和主键外键详解

SQL Server—约束和主键外键详解 约束和主键外键 主键 和 外键 -- 主键: 关系型数据库中一条记录有若干个属性,若其中某一个属性能够位置标识这条记录,这个属性就可以设置为表的主键,主键是确定一条记录的唯一标识,有可能作为主键…...

信息学奥赛复赛复习14-CSP-J2021-03网络连接-字符串处理、数据类型溢出、数据结构Map、find函数、substr函数

PDF文档回复:20241007 1 P7911 [CSP-J 2021] 网络连接 [题目描述] TCP/IP 协议是网络通信领域的一项重要协议。今天你的任务,就是尝试利用这个协议,还原一个简化后的网络连接场景。 在本问题中,计算机分为两大类:服务机&#x…...

Allegro如何合并同名网络铜皮操作指导

Allegro如何合并同名网络铜皮操作指导 Allegro可以将同名网络的铜皮合并起来,如下图,需要把下面两块铜皮合并成一块铜皮 具体操作如下 选择Shape 选择merge shapes Find选择shapes 点击其中一块铜皮,会被亮起来 再点击另外一块铜皮 两块铜皮…...

【探测器】线阵相机中的 TDI 技术

【探测器】线阵相机中的 TDI 技术 1.背景2.TDI相机3.场景应用 1.背景 TDI 即Time Delay Integration时间延迟积分。 TDI相机是线阵相机的一种特殊类型,带有独特的时间延迟积分(TDI)技术。 换句话说,TDI相机是线阵相机的一个高级版…...

k8s 之安装metrics-server

作者:程序那点事儿 日期:2024/01/29 18:25 metrics-server可帮助我们查看pod的cpu和内存占用情况 kubectl top po nginx-deploy-56696fbb5-mzsgg # 报错,需要Metrics API 下载 Metrics 解决 wget https://github.com/kubernetes-sigs/metri…...

java学习-idea编辑器基础使用设置

首先打开电脑中的idea编辑器,点击头部:File按钮 → Settings… 打开设置界面; 设置idea的主题 设置idea代码注释的字体颜色 设置idea编辑器的字体和字体大小 设置idea通过提示回车自动导入包 设置idea输入忽略大小写进行提示...

PDSCH(物理下行共享信道)简介

文章目录 PDSCH(物理下行共享信道)简介1. Transport block CRC attachment2. LDPC base graph selection3. Code block segmentation And Code Block CRC Attachment4. Channel Coding5. Rate Matching6. Code Block Concatenation7. Scrambling8. Modul…...

hutool bug

Hutool参考文档 不用随便升级版本 版本5.8 1: 不要用 ReflectUtil.newInstance(cName); * 和spring 部分框架整合 ,子类转换为父类或者接口失败,报转换失败的错误 https://gitee.com/dromara/hutool/issues/I18NCR?skip_mobiletrue 改成使…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...