我正在与以非OO方式编写的python 2.x API进行交互,它使用模块全局范围来处理某些内部状态驱动的东西。它在不再是单例的上下文中是必需的,修改原始代码(不是我们的代码)不是一种选择。
如果没有使用单独解释器的子进程运行,有没有什么方法可以关闭模块并与模块的多个实例进行交互(从而将其视为对象)?
我需要使用该模块来驱动2种不同的设置 - 它在内部似乎无法使用。
免责声明:请不要这样做。请在非常奇怪的情况下执行此操作 - 并尝试在执行此操作之前以其他方式更改情况。我这样做是为了应对在询问时无法改变的奇怪代码 - 不提供扩展更奇怪代码的方法。
答案 0 :(得分:13)
只需从sys.modules
删除模块:
>>> import sys
>>> import mod as m1
>>> m1.x = 1
>>> del sys.modules['mod']
>>> import mod as m2
>>> m2.x = 2
>>> m1.x
1
答案 1 :(得分:3)
您可以尝试愚弄sys.modules
import badmodule as badmod1
import sys
del sys.modules['badmodule']
import badmodule as badmod2
如果这有效或无效当然取决于坏模块正在做什么......
答案 2 :(得分:1)
我没有亲自使用它,但似乎Exocet库可能有帮助。
答案 3 :(得分:0)
最简单的方法是制作模块的两个副本并单独导入它们。例如,使用您的模块thingabobber
并制作两个名为thingabobber1
和thingabobber2
的副本。然后就是:
import thingabobber1, thingabobber2
如果这不可行,请在最初导入后从sys.modules
删除该模块,以便在第二次导入时获得第二份副本。
import sys
import thingabobber as thingabobber1
del sys.modules["thingabobber"]
import thingabobber as thingabobber2
答案 4 :(得分:0)
这可以通过不同路径导入模块来实现。 也就是说 - 如果在您的sys.path中有两个不同的虚线路径到模块,模块缓存将创建具有不同符号树,全局等的模块的两个不同实例。
这也可用于拥有多个版本的库。
请注意,这会导致异常未被捕获(因为您试图捕获错误的符号)。