Python:当位于不同的目录中时,如何从多个脚本中选择一个作为导入到主脚本中的包



我有多个项目,它们都需要一个公共脚本(main.py(,但我需要它们具有特定于每个项目的不同功能。这意味着,当我运行在项目A中使用的脚本时,我希望能够导入其configA.py,但在为项目B运行时导入configB.py

例如,假设在configA.pyconfigB.py中,对同一函数foo()有不同的定义。我的目标是能够为项目A运行类似于python3 main.py ../../ProjectA/Config/configA.py的程序。然后在main.py中,脚本将导入传递给它的文件(类似于config = import_module(sys.argv[0])(,然后能够运行config.foo(),这将根据传递的文件而有所不同。

通过阅读SO上的许多帮助文章,我看到许多人建议使用importlib.import_module(),因为我可以将包名称作为参数传递给main.py。但与我读过的其他帖子相比,稍微复杂的是我的文件结构。似乎只有当主/包文件在同一目录中,或者当主脚本在包的父目录中时,import_module()才真正起作用。然而,我的文件结构如下:

└─ Documents
├─ Common
│  └─ Scripts
│     └─ main.py
├─ ProjectA
│  └─ Config
│     └─ configA.py
└─ ProjectB
└─ Config
└─ configB.py

有没有一种方法可以让我导入我选择的包,以便在给定此文件结构的main.py中使用?

您可以对不同的导入使用if语句:

import os
import sys
sys.path.insert(0, os.abspath('../..'))  # this is important so the packages are on the path
if sys.argv[1] == 'A':
from ProjectA.Config.configA import foo
elif sys.argv[1] == 'B':
from ProjectB.Config.configB import foo
else:
raise ImportError(f'No module corresponding to {sys.argv[1]}')

或者您也可以使用importlib.import_module而不是if/else链:

import importlib
module = importlib.import_module('Project{x}.Config.config{x}'.format(x=sys.argv[1]))
foo = module.foo

然后通过使用

python main.py A  # use foo from configA
python main.py B  # use foo from ConfigB

Documents通过-m运行

修改sys.path的替代方案是通过Documents目录内的-m交换机运行main.py。当运行python main.py时,脚本的目录将放在路径上。当运行python -m Common.Scripts.main时,当前工作目录将被放在路径上,因此ProjectAProjectB是可自动发现的:

$ pwd
/path/to/Documents
$ python -m Common.Scripts.main

最新更新