Python:如何两次加载模块?

Python:如何两次加载模块?,python,module,load,Python,Module,Load,有没有办法在同一个python会话中加载一个模块两次? 用一个例子来回答这个问题:下面是一个模块: import imp def my_import(name): file, pathname, description = imp.find_module(name) code = compile(file.read(), pathname, "exec", dont_inherit=True) file.close() module = imp.new_modu

有没有办法在同一个python会话中加载一个模块两次?
用一个例子来回答这个问题:下面是一个模块:

import imp

def my_import(name):
    file, pathname, description = imp.find_module(name)
    code = compile(file.read(), pathname, "exec", dont_inherit=True)
    file.close()
    module = imp.new_module(name)
    exec code in module.__dict__
    return module
Mod.py

x = 0
现在我想导入该模块两次,比如创建一个类的两个实例,使其实际上有两个
x
的副本

为了回答评论中的问题,“如果他们可以创建一个以
x
作为变量的类,为什么会有人想这样做”:
您是正确的,但是存在大量必须重写的源代码,并且两次加载模块将是一个快速解决方案。

您可以使用该函数

module1 = __import__("module")
module2 = __import__("module")

编辑:事实证明,这不会导入模块的两个独立版本,相反,
module1
module2
将指向相同的对象,正如Sven所指出的。

是的,您可以加载模块两次:

import mod
import sys
del sys.modules["mod"]
import mod as mod2
现在,
mod
mod2
是同一模块的两个实例

尽管如此,我怀疑这是否有用。改用类——最终会减少工作量

编辑:在Python 2.x中,您还可以使用以下代码“手动”导入模块:

import imp

def my_import(name):
    file, pathname, description = imp.find_module(name)
    code = compile(file.read(), pathname, "exec", dont_inherit=True)
    file.close()
    module = imp.new_module(name)
    exec code in module.__dict__
    return module

这个解决方案可能比第一个更灵活。您不再需要“对抗”导入机制,因为您(部分)正在运行自己的机制。(请注意,此实现不设置模块的
\uuuuuuu文件
\uuuu路径
\uuuuuu包
属性——如果需要这些属性,只需添加代码来设置它们即可。)

从sys.modules中删除条目不一定有效(例如,如果您想在同一个应用程序中使用多个Recury帐户等,则两次导入Recury时将失败。)

实现这一目标的另一种方法是:

>>> import importlib
>>> spec = importlib.util.find_spec(module_name)
>>> instance_one = importlib.util.module_from_spec(spec)
>>> instance_two = importlib.util.module_from_spec(spec)
>>> instance_one == instance_two
False

这将很快,但不是一个解决方案——这将是疯狂的;)您应该研究copy和deepcopy,但我想您应该为您的客户实现它module@F.C.您能否详细说明如何复制或深度复制模块?这不起作用--
module1是module2
将证明它们最终是同一个对象是实现这一点的一种方法,但通常不建议这样做,而且有很好的理由——您真的不应该两次加载一个模块。不过,我不明白为什么
导入模块
,然后
将模块作为mod导入不起作用。如果他们想要的不仅仅是对同一模块的两个引用,这两种方法都不起作用。@Dylnuge这里有一个例子:假设一个模块在导入时加载一个TensorFlow模型(这映射了一些GPU内存和一组TensorFlow图)。您不能重新加载模块,因为它会导致TensorFlow与第一次导入时映射的图形变量和内存冲突的错误,这也不能通过删除模块来解决(这些都在Python之外)。假设在单元测试中,您希望测试导入行为,比如基于
os.environ
变量有选择地加载不同的模型。您想导入相同的模块,但要使用
os.environ
补丁。您好,斯文,谢谢您的回答。它是有效的:)我非常同意,使用类是一个更好的解决方案(如果两次加载一个模块可以被视为一个解决方案)。但就目前而言,这是必须的。试想一下,一个写得很差的包有很多模块,其中到处都是“静态”变量。加载一个模块两次是一种变通方法,直到有人被迫重写包,要么因为它不再可维护,要么因为所有东西都崩溃;)@Woltan:你是在使用Python2.x还是3.x?还有其他方法可以做到这一点,这可能更方便,具体取决于上下文,但它们在不同版本的Python中的工作方式不同。还有什么其他的可能性?@Woltan:我添加了一个替代机制,可以提供更多的控制,因为你可以根据自己的需要调整它。