如何正确动态导入包中的模块以进行开发/测试



我做了一个有很多包和模块的应用程序。我正在开发这些包(在其目录中(,并且由于我在包目录中执行文件,因此模块/包的导入路径会更改。

例如,该项目看起来有点像这样...

├── 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__), '../../'))

最新更新