我有一个名为utils
的python包。它由几个模块和一个将它们连接在一起的__init__.py
文件组成。
__init__.py:
from .modA import util1
from .modB import util2
from .modC import util3
modA.py:
def util1():
print("Util 1")
modB.py:
import flask # <-- Note this import
def util2():
print("Util 2")
modC.py:
def util3():
print("Util 3")
当导入该包的软件运行时,它是在安装了flask的虚拟环境中运行的,所以一切都很好。
我遇到的问题是,如果我在shell中交互运行python
,并执行类似from utils.modC import util3
的操作,即使modC完全不依赖modB,也不导入或使用flask,我仍然会收到modB无法导入flask的错误(假设我没有首先在shell中激活虚拟环境(。
$ python3
Python 3.9.0 (default, Oct 27 2020, 14:15:17)
[Clang 12.0.0 (clang-1200.0.32.21)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from utils.modC import util3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/USERNAME/test/utils/__init__.py", line 2, in <module>
from .modB import util2
File "/Users/USERNAME/test/utils/modB.py", line 1, in <module>
import flask
ModuleNotFoundError: No module named 'flask'
在不修改包的源代码的情况下,我有没有办法在sys.path
中没有flask
的情况下导入util3
(也就是说,它没有尝试导入__init__.py
中列出的所有内容(?
如果做不到这一点,有什么简单的方法可以修改__init__.py
来允许这样做吗?
正如卡巴斯基在这里指出的,你可以用一种肮脏的方式来做:
>>> import sys
>>> sys.path.append("utils")
>>> from modC import util3
>>> util3()
Util 3
或者使用PYTHONPATH env变量间接修改sys.path
。
这是因为当您运行from modC import util3
时,Python将开始在sys.path
中查找名为modC
的模块或包,这与我们运行from utils.modC import util3
时不同,在CCD_14中它查找的是名为CCD15的模块或程序包。将字符串utils
附加到sys.path
,告诉它在万不得已的情况下查找modC
,因为它找不到其他地方,所以它最终会在那里找到它,并将其作为模块而不是包加载。
这显然在某些情况下不起作用,但对我有效