为什么python模块就像一个单例?

Tyl*_*itt 10 python singleton

我作为应用程序运行的一部分,从远程数据库创建一个字典.这个过程非常I/O很重,所以我决定创建这个字典的"单例"实例,并在我的应用程序中调用它.

代码看起来像(in Dictionaries.py):

state_code_dict = None

def get_state_code_dict():
    global state_code_dict
    if state_code_dict == None:
        state_code_dict = generate_state_code_dict()
    return state_code_dict
Run Code Online (Sandbox Code Playgroud)

然后我导入并get_state_code_dict()在需要的地方调用函数.我添加了一个print语句来检查是否state_code_dict正在重新初始化或重用,我发现它正在被重用(这是我想要的功能).为什么state_code_dict应用程序中存活的实例会运行?

编辑

get_state_code_dict在多个文件中导入该函数.

Fre*_*Foo 20

这是Python语言参考对导入模块的工作原理的描述:

(1)找到一个模块,并在必要时进行初始化; (2)在本地名称空间中定义一个或多个名称

(强调补充.)这里,初始化模块意味着执行其代码.仅在必要时才执行此执行,即,如果先前未在当前进程中导入模块.由于Python模块是一流的运行时对象,因此它们有效地成为单例,在首次导入时进行初始化.

请注意,这意味着不需要get_state_dict_code功能; 只需state_code_dict在顶层初始化:

state_code_dict = generate_state_code_dict()
Run Code Online (Sandbox Code Playgroud)

有关更深入的解释,请参阅Thomas Wouters的演讲,特别是.第一部分 - 大约04:20 - 他讨论了"一切都是运行时"的原则.


Kur*_*tal 11

我投了larsmans回答,我只是想补充一个例子.

hello.py:

hi = 'hello'

print(hi)

def print_hi():
    print(hi)
Run Code Online (Sandbox Code Playgroud)

ipython会话:

In [1]: from hello import print_hi
hello

In [2]: print_hi()
hello

In [3]: from hello import print_hi

In [4]: import hello

In [5]: hello.print_hi()
hello
Run Code Online (Sandbox Code Playgroud)


看看第3行和第4行的导入不会像第1行中的导入那样输出"hello",这意味着代码不会被重新执行.