Python 重新加载文件

Python reload file

我有一个脚本可以计算一些东西。它使用来自单独文件 'inputs.py'.

的输入

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

A = 2.3
B = 4.5
C = 3.0

在主文件中,我用

导入它们
from inputs import *

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

reload(inputs)

无效。

非常感谢!

如果您使用的是 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.
from inputs import *

做类似这个伪代码的事情:

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

模块 inputs 缓存在 sys.modules

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

让我们引用文档:

reload(module)

Reload a previously imported module. The argument must be a module object, so it must have been successfully imported before. This is useful if you have edited the module source file using an external editor and want to try out the new version without leaving the Python interpreter. The return value is the module object (the same as the module argument).

参数必须是一个模块对象,所以它必须之前已经成功导入。当你这样做from inputs import *时,你的命名空间中实际上没有模块对象。仅限模块成员。

When reload(module) is executed:

  • Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called a second time.
  • As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
  • The names in the module namespace are updated to point to any new or changed objects.
  • Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.

对旧对象的其他引用(例如模块外部的名称)不会重新绑定以引用新对象,如果需要,必须在它们出现的每个名称空间中进行更新。你明星导入的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