如何在每次更改后无需重启解释器开发Python模块/包?

7 投票
3 回答
834 浏览
提问于 2025-04-15 17:32

我正在用文本编辑器和IPython开发一个Python包。每次我修改模块代码后,都得重启解释器来测试,这真让人头疼,因为我开发的类需要在每次重新加载时重新建立上下文。

我知道有个reload()函数,但这个方法似乎不太受欢迎(而且在Python 3.0中已经不再是内置函数了),而且它很少有效,因为模块通常有多个引用。

我的问题是:有什么好的方法来开发Python模块/包,这样我就不用一直重新建立解释器的上下文了?

我想过一个主意,就是用if __name__ == '__main__':这个技巧直接运行模块,这样代码就不会被导入。但这样会在我的模块文件底部留下很多特定于我设置的上下文杂物。

有什么想法吗?

3 个回答

0

你可以写一个Python脚本,来设置你的环境,然后用下面的命令运行它:

python -i context-setup.py


   -i     When  a  script  is passed as first argument or the -c option is
          used, enter interactive mode after executing the script  or  the
          command.  It does not read the $PYTHONSTARTUP file.  This can be
          useful to inspect global variables  or  a  stack  trace  when  a
          script raises an exception.
3

另一种方法是让你的测试驱动开发更加正式化,而不是用解释器来测试你的模块,可以把测试保存下来,直接运行它们。

你可能知道用Python做这件事的各种方法,我想最简单的开始方式就是把你在解释器里做的操作复制粘贴到文档字符串里,作为一个doctest,然后在你的模块底部添加以下内容:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

这样,每次直接调用这个模块时,你的非正式测试都会被重复执行。这还有很多其他好处。想了解更多关于如何编写doctest的信息,可以查看doctest文档

2

Ipython确实允许重新加载,使用魔法命令 %run 可以做到这一点,详细信息可以查看 iPython 文档

如果某个模块下的内容发生了变化,可以使用递归的 dreloadd() 函数来处理。

如果你有一个复杂的上下文,是否可以在另一个模块中创建它?或者把它赋值给一个全局变量,这样在解释器没有重启的情况下,它就能一直存在。

撰写回答