13

作为应用程序运行的一部分,我从远程数据库创建字典。这个过程是相当繁重的 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()然后我在需要的地方导入并调用该函数。我添加了一个打印语句来检查是否state_code_dict正在重新初始化或重用,我发现它正在被重用(这是我想要的功能)。为什么state_code_dict存活应用程序的实例在运行?

编辑

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

4

2 回答 2

24

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

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

(强调了。)这里,初始化一个模块意味着执行它的代码。此执行仅在必要时执行,即如果模块先前未在当前进程中导入。由于 Python 模块是一流的运行时对象,它们实际上变成了单例,在首次导入时初始化。

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

state_code_dict = generate_state_code_dict()

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

于 2012-06-07T17:35:51.057 回答
14

我投了 larsmans 的回答,我只是想添加一个例子。

你好.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”,这意味着代码没有重新执行。

于 2012-06-07T17:42:58.073 回答