假设 mine.py 想要导入 moduleA 和 moduleB,但是 moduleA 和 moduleB 每个都尝试导入名为“moduleC”的模块。这些是两个不同的模块,它们都恰好被命名为“moduleC”。当运行 mine.py 时,根据 sys.path 的设置,可能会得到正确的“moduleC”,而另一个则会出现意外,从而导致混乱。
如果 moduleA 和 moduleB 是由不同的作者编写的,且我们都不是其中之一,则最好不要修改这些模块。对于 mine.py 的作者是否有可用的解决方案,而不修改 moduleA 或 moduleB?
以下问题询问如何在您是 moduleA 或 moduleB 的作者时解决此问题。 当存在同名模块时,如何从内置库中导入 当存在同名本地模块时,如何在 Python 中访问标准库模块? 我的具体情况 我希望在Python调试器pdb下运行名为PyMOL的程序。不幸的是,PyMOL有一个名为“cmd.py”的文件,它会与pdb导入的通常的cmd发生冲突。
PyMOL安装的相关部分如下:
如果 moduleA 和 moduleB 是由不同的作者编写的,且我们都不是其中之一,则最好不要修改这些模块。对于 mine.py 的作者是否有可用的解决方案,而不修改 moduleA 或 moduleB?
以下问题询问如何在您是 moduleA 或 moduleB 的作者时解决此问题。 当存在同名模块时,如何从内置库中导入 当存在同名本地模块时,如何在 Python 中访问标准库模块? 我的具体情况 我希望在Python调试器pdb下运行名为PyMOL的程序。不幸的是,PyMOL有一个名为“cmd.py”的文件,它会与pdb导入的通常的cmd发生冲突。
PyMOL安装的相关部分如下:
pymol/
__init__.py
cmd.py
PyMOL通过执行__init__.py
来运行。然后,该文件将cmd
作为from pymol import cmd
导入。
根据BrenBarn的指示,我可以成功地使pdb
暂时从sys.path
的前面删除pymol
目录,以便正确导入cmd
。之后,当PyMOL尝试导入其cmd
时,它会崩溃。不知何故,在PyMOL
导入之前但在pdb
导入之后,我需要从导入模块搜索中删除Python的cmd
。
最简示例
$ ls
pymol/
$ ls pymol/
__init__.py cmd.py
init.py
# insert some code into __init__.py directly
import sys
pymol_path = sys.path[0]
sys.path[0] = ""
import pdb
sys.path[0] = pymol_path
from pymol import cmd
# test a sandwich of calls that require each "cmd" modules
pdb.set_trace()
cmd.foo()
pdb.set_trace()
cmd.foo()
print "done!"
# original PyMOL __init__.py code would follow
cmd.py
def foo():
print("cmd.foo()")
试一试
$ PYTHONPATH= python ./pymol/__init__.py
> /Users/khouli/scr/pymol_scr/pymol/__init__.py(11)<module>()
-> cmd.foo()
(Pdb) continue
cmd.foo()
> /Users/khouli/scr/pymol_scr/pymol/__init__.py(13)<module>()
-> cmd.foo()
(Pdb) continue
cmd.foo()
done!
编辑:上述方法现在似乎可以工作,但正如BrenBarn的答案所述,原始问题要求留下所有第三方代码未修改的解决方案可能不存在。这是由于PyMOL中的怪癖导致的。
moduleC
是两个的子包,那么它可能已经可以工作了,因为每个都会导入自己的子包。 - BrenBarn__init__.py
作为脚本运行;这会将其目录放在sys.path
的最前面。直接运行__init__.py
真的是你应该做的吗?通常这不是一个好的实践。 - BrenBarn