如何在使用“python -i”进行交互式解释时重新加载Python源文件

17

在编写或调试Python程序时,我喜欢使用-i命令行开关,以便直接检查我的函数,而不必从头到尾地运行所有内容。

但是,每当我更改代码时,我必须关闭和重新启动交互式会话,从而丢失可能定义的所有临时变量。我该如何在Python解释器中重新加载源文件?


内置函数reload看起来就是为此而生,但我只能使用它与命名模块一起使用:

>> import my_prog
>> print my_prog.x
-- prints an error, because x is not defined --

-- edited my_prog.py to add the x global now...
>> reload(my_prog)
>> print my_prog.x
-- prints x

然而,如果我在一开始使用from my_prog import *,那么重新加载无法起作用,再次进行导入也没有效果。

3个回答

25

这与Python缓存模块的方式有关。您需要一个模块对象来传递给reload,并需要重复导入命令。也许有更好的方法,但以下是我通常使用的方法: 在Python 3中:

>> from importlib import reload
>> import my_prog
>> from my_prog import *
*** Run some code and debug ***
>> reload(my_prog); from my_prog import *
*** Run some code and debug ***
>> reload(my_prog); from my_prog import *
在Python 2中,reload是内置的,因此您可以只删除第一行。

好的,谢谢!@smaplebias为那些对细节感兴趣的人提供了更详细的描述。我给一个赞。 - Carl F.
这是一个有用的技巧,谢谢。 但要注意过时/残留的符号:假设你有一个调用bar()的函数foo(),并且你决定将bar重命名为baz。 只是你忘记编辑foo的主体,所以它仍然调用bar()(在重新加载后仍然有效)。 在你意识到之前,你已经花了半天时间进行调试。 - wildekat

11

当你使用 from my_prog import * 时,你将符号引入解释器的全局作用域,因此 reload() 无法更改这些全局符号。只有在重新编译和重新加载模块时,才会更改模块级别的属性。

例如:myprog.py

x = 1

在解释器中:

>>> import myprog
>>> myprog.x
1
>>> from myprog import x
>>> x
1

现在编辑myprog.py,将x = 2进行设置:

>>> reload(myprog)
>>> myprog.x
2
>>> x
1

再次执行 from myprog import * 将符号重新拉回到全局作用域中:

>>> reload(myprog)
>>> from myprog import *

2
如果不提及Python 3的重大变化,这就有点过时了:https://dev59.com/P2kw5IYBdhLWcg3wGGq8#10142772 - matanster

0
我明白了。例如,我们使用以下命令进入交互模式:
python3 -i filename.py

然后使用 importlib 包重新加载它,如下所示:

from importlib import reload
reload(filename) # Need no quotatiom mark

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