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

时间:2012-06-07 17:21:05

标签: python singleton

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

代码看起来像(在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

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

修改

我在多个文件中导入get_state_code_dict函数。

2 个答案:

答案 0 :(得分:17)

这是Python语言参考对how importing a module works

的描述
  

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

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

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

state_code_dict = generate_state_code_dict()

有关更深入的解释,请参阅this talk by Thomas Wouters,尤其是第一部分 - 大约04:20 - 他讨论了“一切都是运行时”的原则。

答案 1 :(得分:10)

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

<强> hello.py:

hi = 'hello'

print(hi)

def print_hi():
    print(hi)

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


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