场景:一个模块化应用程序,可以在运行时动态加载.py模块。程序员(我)希望编辑模块的代码,然后将其重新加载到程序中而不停止执行。
可以这样做吗?
我已尝试在更新的module.py上第二次运行导入,但未获取更改
答案 0 :(得分:6)
虽然reload
重新加载了一个模块,但正如另一个答案所提到的那样,你需要采取相当多的预防措施才能使其顺利运行 - 对于某些你认为可以轻松工作的事情,你需要做的很好实际需要的工作量令人震惊。
如果您使用的格式为from module import afunction
,那么您几乎可以确保reload
不起作用:您必须完全导入模块,永远不会强大的>函数,类等,来自模块内部,如果你希望reload
做任何有用的事情都有希望(否则你必须以某种方式追逐从这里和那里导入的所有零碎的东西)模块,并重新绑定它们中的每一个 - eep ;-)。请注意,无论如何,我更喜欢遵循此规则,无论我是否计划进行任何重新加载,但是,重新加载时,它至关重要。
困难的问题是:如果你在任何地方活着,在模块的先前版本中存在类的实例,reload
本身将完全没有升级这些实例。 那个问题确实很难; Python Cookbook(第2版)中最长,最难的配方之一就是如何编写模块代码以支持这种“实际升级现有实例的重新加载”。这当然只有你用OOP风格编程才有意义,但是......任何复杂到足以需要“重新加载这个插件”功能的Python程序非常可能会有很多OOP,所以它是这不是一个小问题。
docs for reload非常完整,确实提到了这个问题,但没有提示如何解决它。来自Python Cookbook在线的Michael Hudson的This recipe更好,但它只是我们演变成印刷版(第2版) - 食谱20.15的开始,其在线版本是here (不完整,除非您注册O'Reilly商业在线图书服务的免费时间限制预览)。
答案 1 :(得分:0)
reload()会做你需要的。您只需要注意重新编译时模块中执行的代码;如果您的模块只包含定义,通常最简单。
答案 2 :(得分:0)
答案 3 :(得分:0)
您可以从livecoding模块中获得一些用途。
答案 4 :(得分:0)
但是,由于您正在处理的这些模块是您自己的,并且您只编辑它们,因此可以实现某种本地重新加载机制,而不是依赖于内置重新加载。您可以将模块加载器设计为加载文件,编译并将其转换为特定命名空间并告知调用代码已准备就绪的内容。您可以通过确保有一个合适的init
函数来重新初始化模块来处理重新加载。我假设你只会编辑这些。
这是一项工作,但可能很有趣,值得你花时间。