我做了一个有很多包和模块的应用程序。我正在开发这些包(在其目录中(,并且由于我在包目录中执行文件,因此模块/包的导入路径会更改。
例如,该项目看起来有点像这样...
├── app.py
└── utils
├── database.py
└── robot
├── __init__.py
├── run.py
├── recognition.py
└── housekeeping.py
如果我执行了python3 app.py
那么import utils.database
是有效的。
但是,如果我在包中并运行python3 run.py
那么import utils.database
是无效的。
我想知道如何执行函数并导入模块/包而不会出错。
我已经工作了,但我认为这是不对的。到目前为止,我已经尝试在每个主.py
文件中使用__name__ == "__main__"
并使用sys.path.append
,但我觉得一定有一种更简单的更好看的方法。
这就是run.py
内部的样子,我也不得不在database.py
中做同样的事情,这是最好的方法吗?
if __name__ == "__main__":
import sys
sys.path.append('../../')
from utils.robot.recognition import *
from utils.robot.housekeeping import *
import utils.database as db
将$PYTHONPATH
环境变量设置为包含utils
的目录,然后您的导入将起作用。
切勿直接运行包中包含的模块。 如果直接运行相同的模块并且可以从包中导入,这是有问题的,因为这样解释器中将有两个模块副本,这保证了混淆。
相反,请使用-m
解释器选项:
python -m utils.robot.run
或者,如果您永远不需要从其他模块导入 run.py,则可以从包中完全删除该文件并将其保存在单独的"scripts"目录中,然后就不需要使用-m
. 但是您仍然需要设置 sys.path,要么像以前一样使用$PYTHONPATH
,要么通过执行 sys.path 操作。 如果您选择执行 sys.path 操作,那么无论当前工作目录是什么,您都应该使其正常工作:
sys.path.append(os.path.join(os.path.dirname(__file__), '../../'))