简体   繁体   English

具有多个导入的Python模块全局变量

[英]Python module globals with multiple imports

What code is run, and what is not, when a module is imported in python? 在python中导入模块时运行什么代码,什么不运行?

What code is run, and what is not, when a module is imported for the second time in python? 在python中第二次导入模块时运行什么代码,什么不运行?

module1.py : module1.py

GLOBAL_VAR = 'orig'

print('module1: GLOBAL_VAR = {}'.format(GLOBAL_VAR))

def init():
    global GLOBAL_VAR
    print('module1:init(1): GLOBAL_VAR = {}'.format(GLOBAL_VAR))
    GLOBAL_VAR = 'changed'
    print('module1:init(2): GLOBAL_VAR = {}'.format(GLOBAL_VAR))

module2.py : module2.py

print('module2: importing module1')
import module1

print('module2(1): module1.GLOBAL_VAR = {}'.format(module1.GLOBAL_VAR))

module1.init()

print('module2(2): module1.GLOBAL_VAR = {}'.format(module1.GLOBAL_VAR))

module3.py : module3.py

print('module3: importing module1')
import module1

print('module3(1): module1.GLOBAL_VAR = {}'.format(module1.GLOBAL_VAR))

main.py : main.py

import module2
import module3

Output : 输出

python3 main.py

module2: importing module1
module1: GLOBAL_VAR = orig
module2(1): module1.GLOBAL_VAR = orig
module1:init(1): GLOBAL_VAR = orig
module1:init(2): GLOBAL_VAR = changed
module2(2): module1.GLOBAL_VAR = changed
module3: importing module1
module3(1): module1.GLOBAL_VAR = changed

Basically, the "freestanding" - not in a function, not in a class - code runs only once. 基本上,“独立” - 不在函数中,而不在类中 - 代码只运行一次。 I would like to know more about this, how this works, what are the limitations, especially, when is this not true? 我想更多地了解这个,它是如何工作的,有什么限制,特别是什么时候这不正确?

My hunch is, that imported modules, even if they are imported from different modules, are registered at "per interpreter" level, and the interpreter knows if the code within the module is already run, and after that, it maintains the current state of any module in an object, and every importer gets that maintained object. 我的预感是,导入的模块,即使它们是从不同的模块导入,也是在“每个解释器”级别注册的,并且解释器知道模块中的代码是否已经运行,之后,它保持当前状态对象中的任何模块,每个导入器都获取该维护对象。

But what can mess it up? 但有什么可以弄乱的呢? What if I use threads, and a second module imports the X module, but X module has a very long code to execute, and did not finish by the time the second import gets a timeslot? 如果我使用线程,第二个模块导入X模块,但X模块有很长的代码要执行,并且在第二次导入获得时间段时没有完成,该怎么办? What will become of this whole system, if I am using multiprocessing? 如果我使用多处理,整个系统会变成什么样?

Unfortunately I did not find a good explanation. 不幸的是我没有找到一个好的解释。

So, I already tested how it works in a basic setup, I already know that much, my question is why does it work so, what is the underlying mechanism? 所以,我已经测试了它在基本设置中是如何工作的,我已经知道了很多,我的问题是为什么它可以工作,底层机制是什么?

You are correct in stating that all top-level code is executed upon being imported for the first time. 你说的是所有顶级代码都是在第一次导入时执行的。 This includes function definitions (but not their body) which bind the function's name to the function object. 这包括将函数名称绑定到函数对象的函数定义(但不是它们的主体)。

As soon as a module is imported, it is stored in sys.modules . 导入模块后,它将存储在sys.modules This is a dict mapping module names to the module object. 这是一个dict映射模块名称到模块对象。 So, after import module_a you could refer to it as sys.modules['module_a'] . 因此,在import module_a您可以将其称为sys.modules['module_a'] You can even delete it from the dict (see What does "del sys.modules[module]" actually do? for consequences of doing so). 你甚至可以从dict中删除它(参见“del sys.modules [module]”实际上做了什么?这样做的后果)。 If you don't delete the module from sys.modules , all future imports simply get the object from there. 如果不从sys.modules删除模块,则所有将来的导入都只是从那里获取对象。 You can find a detailed description of the import system here: https://docs.python.org/3/reference/import.html 您可以在此处找到导入系统的详细说明: https//docs.python.org/3/reference/import.html

As for multi-threading, this is usually a non-issue because of the global interpreter lock (GIL): https://docs.python.org/3/c-api/init.html?highlight=gil#thread-state-and-the-global-interpreter-lock 至于多线程,由于全局解释器锁(GIL),这通常不是问题: https ://docs.python.org/3/c-api/init.html highlight = gil#thread-state -和-的-全球翻译锁

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM