Python 重新加载文件

22

我有一个计算一些内容的脚本。它使用了来自一个名为'inputs.py'的单独文件中的输入。

'inputs.py' 中只有几个变量:

A = 2.3
B = 4.5
C = 3.0

在主文件中,我使用以下方式导入它们

from inputs import *

如果我现在更改了'inputs.py'中的内容并再次执行脚本,它仍然使用旧值而不是新值。我该如何重新加载文件?

reload(inputs)

无法工作。

提前致谢!


你正在使用Python 3吗? - Anand S Kumar
如果使用Python3,请使用importlib.reload - Bhargav Rao
我正在使用 ipython 2.4.1。 - Sebastian
可能是如何在导入后重新导入模块以更改代码的重复问题。 - Rajat
3个回答

36

如果您正在使用Python 3.x,则要重新加载已使用from module import name导入的名称,您需要执行以下操作 -

import importlib
import inputs #import the module here, so that it can be reloaded.
importlib.reload(inputs)
from inputs import A # or whatever name you want.

对于 Python 2.x 版本,您可以简单地执行以下操作 -

import inputs   #import the module here, so that it can be reloaded.
reload(inputs)
from inputs import A # or whatever name you want.

1
第四行是多余的,你可以简单地这样做:inputs = importlib.reload(inputs)。 - MCSH

7

让我们引用文档:

reload(module)

重新加载以前导入的模块。参数必须是一个模块对象,因此它必须在导入成功之后。如果您使用外部编辑器编辑了模块源文件,并希望在不离开Python解释器的情况下尝试新版本,则此选项非常有用。返回值是模块对象(与模块参数相同)。

参数必须是一个模块对象,因此它必须在导入成功之后。 当你使用from inputs import *时,实际上在你的命名空间中没有模块对象,只有模块成员。

执行reload(module)时:

  • Python模块的代码将被重新编译,并重新执行模块级别的代码,定义一组新的对象,这些对象绑定到模块字典中的名称。扩展模块的init函数不会第二次调用。
  • 与Python中的所有其他对象一样,仅当其引用计数降至零时,旧对象才会被回收。
  • 模块命名空间中的名称将更新为指向任何新对象或更改的对象。
  • 对旧对象的其他引用(例如模块外部的名称)不会重新绑定到新对象,并且必须在它们出现的每个命名空间中更新,如果需要的话。

对旧对象的其他引用(例如模块外部的名称)不会重新绑定到新对象,并且必须在它们出现的每个命名空间中更新,如果需要的话。 你导入的A、B和C恰好是其他引用。

总之,一个示例代码如下:

import os  # see below

# fake module before changes
with open('inputs.py', 'w') as f:
    f.write("a, b, c = 1, 2, 3")

import inputs

# check if all members are correct
assert inputs.a == 1
assert inputs.b == 2
assert inputs.c == 3

os.unlink('inputs.pyc')  # Remove previously compiled byte-code.
# I'm now sure if it's mandatory, anyway for some reason Python
# does not recompile inputs.py in my experiments. 

# New fake file
with open('inputs.py', 'w') as f:
    f.write("a, b, c = 4, 5, 6")

reload(inputs)

# check if members has changes
assert inputs.a == 4
assert inputs.b == 5
assert inputs.c == 6

0
from inputs import *

类似于以下伪代码的操作:

import inputs as temporary
for all names in temporary:
    (name) = temporary.name
del temporary

inputs 模块被缓存在 sys.modules 中。

如果你执行 reload(inputs),缓存的模块会被重新加载,但是将数据从导入的模块加载到本地命名空间的赋值过程不会重复。你必须手动执行此操作,正如其他答案已经说明的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接