Azure ML管道中子进程访问自定义模块的PYTHONPATH配置问题
解决Azure ML管道中自定义模块导入失败问题
项目结构
. ├── my_custom_module │ └── __init__.py │ └── ... ├── scripts │ ├── start_script.py │ └── example.py
问题场景
在Azure ML Studio管道中运行start_script.py,该脚本通过subprocess.run(['python3.9', "scripts/example.py"], check=True)执行example.py,但example.py中from my_custom_module import some_class语句抛出ModuleNotFoundError: No module named my_custom_module,原因是自定义模块路径未加入PYTHONPATH。
调试信息
# start_script.py和example.py中os.getcwd()返回值: /mnt/azureml/cr/j/e9e/exe/wd # start_script.py和example.py中打印sys.path的返回值: /mnt/azureml/cr/j/21d/exe/wd/scripts /azureml-envs/azureml_e9e/lib/python39.zip /azureml-envs/azureml_e9e/lib/python3.9 /azureml-envs/azureml_e9e/lib/python3.9/lib-dynload /azureml-envs/azureml_e9e/lib/python3.9/site-packages /mnt/azureml/cr/j/21d/exe/wd /azureml-envs/azureml_e9e/lib/python3.9/site-packages/azureml/_project/vendor # start_script.py中os.system(which python)的返回值: /azureml-envs/azureml_e9e/bin/python # example.py中os.system(which python)无返回值
已尝试的无效方法
# 通过os.system设置PYTHONPATH,仅对当前shell进程生效,子进程无法继承 os.system(f"export PYTHONPATH=$PYTHONPATH:{os.getcwd()}") os.system(f"export PYTHONPATH=$PYTHONPATH:{os.getcwd() + '/my_custom_module'}") # 修改start_script.py的sys.path,仅对父进程生效,子进程不受影响 sys.path.append(os.getcwd() + "/my_custom_module")
可行解决方案
1. 在subprocess中显式传递修改后的PYTHONPATH
子进程不会继承父进程通过os.system设置的环境变量,但可以通过env参数手动传递修改后的环境变量:
import os import subprocess # 复制当前环境变量,避免覆盖原有配置 env = os.environ.copy() # 将项目根目录(my_custom_module所在目录)添加到PYTHONPATH project_root = os.getcwd() env['PYTHONPATH'] = f"{project_root}:{env.get('PYTHONPATH', '')}" # 调用example.py时传入修改后的环境变量 subprocess.run(['python3.9', "scripts/example.py"], check=True, env=env)
2. 在example.py中直接添加模块路径到sys.path
直接在example.py开头添加项目根目录到sys.path,确保导入时能找到自定义模块:
import sys import os # 获取项目根目录(当前工作目录即为项目根) project_root = os.getcwd() sys.path.append(project_root) # 正常导入自定义模块 from my_custom_module import some_class
3. 使用相对导入(需调整脚本结构)
若要使用相对导入,需将scripts目录转为Python包,并调整调用方式:
- 在
scripts目录下创建空的__init__.py文件 - 修改
start_script.py中的subprocess调用,以模块方式运行example.py:import os import subprocess # 以模块方式运行,工作目录保持项目根 subprocess.run(['python3.9', '-m', 'scripts.example'], check=True, cwd=os.getcwd()) - 修改
example.py中的导入语句为相对导入:from ..my_custom_module import some_class
内容的提问来源于stack exchange,提问作者mayool
相关产品推荐
相关产品推荐

