[英]Is it possible to import a single module from a Python package?
I have a python package called utils
.我有一个名为
utils
的 python 包。 It consists of a few modules, and an __init__.py
file tying them all together.它由几个模块和一个将它们捆绑在一起的
__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")
When the software is running that imports this package, it's running in a virtual environment that has flask installed, so everything works fine.当导入这个包的软件运行时,它运行在一个安装了烧瓶的虚拟环境中,所以一切正常。
The problem I'm having is that if I interactively run python
in my shell, and do something like from utils.modC import util3
, even though modC has absolutely no reliance on modB, and doesn't import, or use flask, I'm still going to get an error that modB couldn't import flask (assuming I didn't activate the virtual environment in my shell first).我遇到的问题是,如果我在 shell 中以交互方式运行
python
,并执行类似from utils.modC import util3
,即使 modC 绝对不依赖 modB,并且不导入或使用烧瓶,我我仍然会得到一个错误,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'
Without modifying the source code of the package, is there any way for me to import util3
without having flask
in my sys.path
(AKA without it trying to import everything listed in __init__.py
)?在不修改包的源代码的情况下,有什么方法可以让我导入
util3
而我的sys.path
flask
没有flask
(也就是没有尝试导入__init__.py
列出的所有内容)?
Failing that, is there any simple way to modify __init__.py
to allow this?否则,是否有任何简单的方法可以修改
__init__.py
以允许这样做?
As kaspersky pointed out here , you can do it in a dirty way:正如卡巴斯基在这里指出的,你可以用一种肮脏的方式来做到这一点:
>>> import sys
>>> sys.path.append("utils")
>>> from modC import util3
>>> util3()
Util 3
Or use the PYTHONPATH env variable to modify sys.path
indirectly.或者使用 PYTHONPATH 环境变量间接修改
sys.path
。
This works because when you run from modC import util3
, Python will start looking through sys.path
for a module or package named modC
, which is different than when we ran from utils.modC import util3
, where it was looking for a module or package named utils
.这是有效的,因为当你
from modC import util3
运行时,Python 将开始通过sys.path
查找名为modC
的模块或包,这与我们from utils.modC import util3
运行时不同,它在那里寻找模块或包名为utils
。 Appending the string utils
to sys.path
tells it to look there as a last resort, and because there are no other places it will find modC
, it will eventually find it there and load it as a module, rather than a package.将字符串
utils
附加到sys.path
告诉它作为最后的手段查看那里,因为没有其他地方它会找到modC
,它最终会在那里找到它并将其作为模块而不是包加载。
This apparently won't work in some cases, but works for me.这在某些情况下显然不起作用,但对我有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.