我注意到一些奇怪的情况,例如以下测试失败:
x = <a function from some module, passed around some big application for a while>
mod = __import__(x.__module__)
x_ref = getattr(mod, x.__name__)
assert x_ref is x # Fails
(这样的代码出现在pickle模块中)
我认为我没有任何导入钩子,重载调用或sys.modules操作,这些操作会破坏python的正常导入缓存行为。
为什么模块会被加载两次还有其他原因吗?我已经看到了关于此的说法(例如,https://stackoverflow.com/a/10989692/1332492),但我无法用简单,孤立的脚本重现它。
答案 0 :(得分:3)
我相信你误解了__import__
的工作方式:
>>> from my_package import my_module
>>> my_module.function.__module__
'my_package.my_module'
>>> __import__(my_module.function.__module__)
<module 'my_package' from './my_package/__init__.py'>
来自文档:
当name变量的格式为
package.module
时,通常是 返回顶级包(直到第一个点的名称),而不是 按名称命名的模块。但是,当非空fromlist
时 给出参数,返回名称命名的模块。
正如您所看到的,__import__
不会返回子模块,而只返回 top 包。如果您还在包级别定义了function
,则 确实会对其进行不同的引用。
如果您只想加载模块,则应使用importlib.import_module
代替__import__
。
至于回答你的实际问题:AFAIK没有办法导入同一个模块,同名,两次没有搞乱导入机制。但是,您可以拥有sys.path
中也可用的包的子模块,在这种情况下,可以使用不同的名称 将其导入两次:
from some.package import submodule
import submodule as submodule2
print(submodule is submodule2) # False. They have *no* relationships.
这有时会导致问题,例如pickle
。如果您挑选submodule
引用的内容,则无法使用submodule2
作为参考来解开它。
但是这并没有解决您提供给我们的具体示例,因为使用__module__
属性导入应返回正确的模块。