【问题标题】:Why does a python module act like a singleton?为什么 python 模块表现得像一个单例?
【发布时间】:2012-06-11 19:07:04
【问题描述】:

作为应用程序运行的一部分,我从远程数据库创建字典。这个过程是相当繁重的 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 函数。

【问题讨论】:

  • 因为导入的代码只在第一次执行?
  • 编辑澄清:我在多个位置导入代码(多个文件包括get_state_code_dict 函数。
  • 默认情况下,导入解释器已经加载的代码不会重新加载该代码。可以故意重新加载一个模块,但如果你必须这样做,而不是因为模块的实际代码可能在运行时发生了变化,你应该使用不同的编程习惯来做你想做的事情。跨度>
  • 而这种行为正是可取的,因为模块初始化有时是重量级的。

标签: python singleton


【解决方案1】:

这是 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 — 他讨论了“一切都是运行时”原则。

【讨论】:

  • 然后我可以通过调用import Dictionaries; state_code_dict = Dictionaries.state_code_dict 来获取 state_code_dict 吗?
  • @TylerDeWitt:是的。或者通过惯用的from Dictionaries import state_code_dict
【解决方案2】:

我投了 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”,这意味着代码没有重新执行。

【讨论】:

    猜你喜欢
    • 2019-04-24
    • 1970-01-01
    • 2016-09-04
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多