[英]How to reload python module imported using `from module import *`
I saw in this useful Q&A that one can use reload(whatever_module)
or, in Python 3, imp.reload(whatever_module)
.我在这个有用的问答中看到可以使用
reload(whatever_module)
或者在 Python 3 中imp.reload(whatever_module)
。
My question is, what if I had said from whatever_module import *
to import?我的问题是,如果我说
from whatever_module import *
到import 会怎样? Then I have no whatever_module
to refer to when I use reload()
.然后,当我使用
reload()
时,我没有whatever_module
可参考的模块。 Are you guys gonna yell at me for throwing a whole module into the global namespace?你们会因为我把整个模块扔进全局命名空间而对我大喊大叫吗? :)
:)
I agree with the "don't do this generally" consensus, but... 我同意“不要这样做”的共识,但......
The correct answer is: 正确答案是:
import X
reload(X)
from X import Y # or * for that matter
Never use import *
; 切勿使用
import *
; it destroys readability. 它破坏了可读性。
Also, be aware that reloading modules is almost never useful. 另外,请注意重新加载模块几乎从不有用。 You can't predict what state your program will end up in after reloading a module, so it's a great way to get incomprehensible, unreproduceable bugs.
你无法预测你的程序在重新加载模块后最终会处于什么状态,所以这是获得难以理解的,无法解决的错误的好方法。
A 一个
from module import *
takes all “exported” objects from module
and binds them to module-level (or whatever-your-scope-was-level) names. 从
module
获取所有“导出”对象,并将它们绑定到模块级别(或任何您的范围级别)名称。 You can reload the module as: 您可以将模块重新加载为:
reload(sys.modules['module'])
but that won't do you any good: the whatever-your-scope-was-level names still point at the old objects. 但这对你没有任何好处:无论你的范围是什么级别的名字仍然指向旧的对象。
A cleaner answer is a mix of Catskul's good answer and Ohad Cohen's use of sys.module
and direct redefinition: 一个更清晰的答案是Catskul的好答案和Ohad Cohen使用
sys.module
和直接重新定义的混合:
import sys
Y = reload(sys.module["X"]).Y # reload() returns the new module
In fact, doing import X
creates a new symbol ( X
) that might be redefined in the code that follows, which is unnecessary (whereas sys
is a common module, so this should not happen). 事实上,执行
import X
会创建一个新的符号( X
),可能会在后面的代码中重新定义,这是不必要的(而sys
是一个常见的模块,所以这不应该发生)。
The interesting point here is that from X import Y
does not add X
to the namespace, but adds module X
to the list of known modules ( sys.modules
), which allows the module to be reloaded (and its new contents accessed). 这里有趣的一点是,
from X import Y
不会将X
添加到命名空间,而是将模块X
添加到已知模块列表( sys.modules
),这允许重新加载模块(并访问其新内容)。
More generally, if multiple imported symbols need to be updated, it is then more convenient to import them like this: 更一般地说,如果需要更新多个导入的符号,则可以更方便地导入它们,如下所示:
import sys
reload(sys.module["X"]) # No X symbol created!
from X import Y, Z, T
I've found another way to deal with reloading a module when importing like:我找到了另一种在导入时处理重新加载模块的方法,例如:
from directory.module import my_func
It's nice to know how do modules are being imported generally.很高兴知道模块是如何被导入的。 The module is searched in
sys.modules
dictionary.该模块在
sys.modules
字典中搜索。 If it already exists in sys.modules - the module will not be imported again.如果它已经存在于 sys.modules - 该模块将不会被再次导入。
So if we would like to reload our module, we can just remove it from sys.modules and import again:因此,如果我们想重新加载我们的模块,我们可以将其从 sys.modules 中删除并再次导入:
import sys
from directory.module import my_func
my_func('spam')
# output: 'spam'
# here I have edited my_func in module.py
my_func('spam') # same result as above
#output: 'spam'
del sys.modules[my_func.__module__]
from directory.module import my_func
my_func('spam') # new result
#output: 'spam spam spam spam spam'
If You would like to get reloaded module when running whole script, you could use exception handler:如果您想在运行整个脚本时重新加载模块,您可以使用异常处理程序:
try:
del sys.modules[my_func.__module__]
except NameError as e:
print("""Can't remove module that haven't been imported.
Error: {}""".format(e))
from utils.module import my_func
..........
# code of the script here
When importing using from whatever_module import whatever
, whatever
is counted as part of the importing module, so to reload it - you should reload your module. 当使用
from whatever_module import whatever
, whatever
是否计入导入模块的一部分,所以要重新加载它 - 您应该重新加载模块。 But just reloading your module you will still get the old whatever
- from the already-imported whatever_module
, so you need to reload(whatever_module), and than reload your module: 但就重装你的模块,你仍然会得到老
whatever
-从已经进口whatever_module
,所以你需要重新加载(whatever_module),比重装你的模块:
# reload(whatever_module), if you imported it
reload(sys.modules['whatever_module'])
reload(sys.modules[__name__])
if you used from whatever_module import whatever
you can also consider 如果你使用
from whatever_module import whatever
你也可以考虑
whatever=reload(sys.modules['whatever_module']).whatever
or 要么
whatever=reload(whatever_module).whatever
import re
for mod in sys.modules.values():
if re.search('name', str(mod)):
reload(mod)
for python 3.7 : 对于python 3.7:
from importlib import reload #import function "reload"
import YourModule #import your any modules
reload(YourModule) #reload your module
Reload function can be called from your own function 可以从您自己的函数调用重新加载功能
def yourFunc():
reload(YourModule)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.