【问题标题】:Why this reload fails with "NameError: name <xxx> is not defined"?为什么此重新加载失败并显示“NameError: name <xxx> is not defined”?
【发布时间】:2026-01-19 14:55:02
【问题描述】:

文件:foo_module.py

#file: foo_module.py
def foo():
    print("Am foo v1")

文件:attempt1.py

#file: attempt1.py
import sys
from time import sleep
from importlib import reload
import foo_module  # <-- import the entire module

print(sys.modules['foo_module']) #Lets see if the module is loaded
while True:
    foo_module.foo()

    #simulate a delay or a condition by when foo_module would have changed
    sleep(2)

    #should reload foo_module to get the latest
    reload(foo_module)

输出:

<module 'foo_module' from 'D:\\pyth\\foo_module.py'>
Am foo v1
Am foo v1
Am foo v1 # I go in around this time and change the foo_module print statement to simulate update to a loaded module
Am foo v2 # Voila ! reload works !
Am foo v2
Am foo v2

这很好,可以按我的预期工作。 但以下不起作用!

文件:attempt2.py

#file: attempt2.py
import sys
from time import sleep
from importlib import reload
from foo_module import foo  # <-- import specific item only

#Lets see if the module is loaded
print(sys.modules['foo_module']) 

while True:
    foo()

    #simulate a delay or a condition by when foo_module would have changed
    sleep(2)

    #try to reload foo_module to get the latest
    reload(foo_module) #FAILS !

输出:

<module 'foo_module' from 'D:/pyth\\foo_module.py'>  # <-- Module is loaded. isnt it ?
Am foo v1
Traceback (most recent call last):
  File "D:/pyth/attempt2.py", line 10, in <module>
    reload(foo_module)
NameError: name 'foo_module' is not defined

但是 sys.modules 在这两种情况下似乎都有 foo_module 的条目! 我错过了什么?

【问题讨论】:

    标签: python python-3.x python-module sys


    【解决方案1】:

    感谢https://*.com/a/46814062/237105

    # Reload via sys.modules as it is not imported directly
    reload(sys.modules['foo_module'])
    # Then, reimport function
    from foo_module import foo
    

    你的总代码,固定:

    import sys
    from time import sleep
    from importlib import reload
    from foo_module import foo  # <-- import specific item only
    
    print(sys.modules['foo_module'])
    while True:
        foo()
    
        # simulate a delay or a condition by when foo_module would have changed
        sleep(2)
    
        # reload foo_module via sys.modules as it is not imported directly
        reload(sys.modules['foo_module'])
    
        # re-import foo to update it.
        from foo_module import foo
    

    【讨论】:

    • 因为 foo_module 在当前范围内不可见,所以您从未导入过它。这就是原始代码失败的原因。因此您需要通过 sys.modules 访问它。
    • 如果它不直接可见,from foo_module import foo 怎么会在问题行上方的一行中工作?
    • 我想你误会了。这是关于在当前上下文中可以使用哪些名称。而from foo_module import foo 只导入名称foo,而不是foo_module。因此,如果您通过foo_module.foo() 调用它,它会给您同样的错误。如果foo_module 在当前范围内不能用作名称,则不能将其传递给reload()。尽管如此,当您导入foo 时,您当然加载了该模块,因此它在sys.modules 中可用。但由于它不能作为名称使用,您必须通过sys.modules 访问它。
    • 是的。 import 搜索模块,对于reload,模块需要已经被导入。 import 是一个 python 命令,reload() 是一个函数。大不同。
    • 好吧,它不能。该命令永远不会到达reload() 函数。如果你仔细看,你没有给reload()一个字符串,你给它一个名字:reload(foo_module)不是reload('foo_module')。 Python 已经出错了,因为在调用 reload() 之前它不知道 foo_module 应该是什么。
    最近更新 更多