微商网站制作,网站自己的,如何看一个关键词在某个网站是否被百度收录,岳阳网站建设制作在开发大型 Python 应用程序时#xff0c;有时需要多个模块共享和管理全局数据。如何优雅地在 Python 包内的不同模块间共享全局数据是一个常见的设计问题。我们希望避免全局变量的混乱和难以维护的代码#xff0c;但同时能够安全、高效地管理这些共享数据。 
下面我们将探讨…在开发大型 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 包中管理全局数据的方法有多种具体选择取决于应用的规模和需求 
简单项目可以使用专门的模块存储全局数据适用于全局数据较少且简单的情况。面向对象项目使用单例模式是一个更优雅的选择尤其在需要数据封装时。多线程/异步项目contextvars 提供了线程安全的全局数据管理方法。结构化数据使用 dataclasses 或配置对象可以提供更强的数据结构化管理。跨进程环境变量适合用于跨进程或容器化应用。 
根据项目的需求和复杂度选择合适的全局数据管理方法能够提高代码的可维护性和可扩展性。