NodeJS调用Python脚本时本地模块导入失败问题求助
NodeJS调用Python脚本时本地模块导入失败的解决方案
从NodeJS通过PythonShell或child_process.spawn调用Python脚本时,标准库导入正常,但本地utils模块出现ModuleNotFoundError,直接运行Python脚本无问题。根源是Python运行时的模块搜索路径未包含backend/src目录,而NodeJS调用时的工作目录与直接运行Python时不同。
方案一:在Python脚本中手动添加模块搜索路径
修改resource_logs.py,在导入utils前将backend/src目录加入Python的模块搜索路径:
import sys import os # 获取当前脚本的绝对路径,推导backend/src目录 script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) backend_src_dir = os.path.dirname(script_dir) # 将backend/src加入sys.path sys.path.append(backend_src_dir) # 现在可以正常导入utils模块 from utils import secrets print("Printed in the python script")
原理:强制把backend/src加入Python的模块搜索列表,无论Python进程的工作目录在哪里,都能找到utils模块。
方案二:在NodeJS中设置PYTHONPATH环境变量
通过PythonShell的配置项,将backend/src路径添加到Python的PYTHONPATH环境变量中:
const {PythonShell} = require('python-shell'); const path = require('path'); // 生成backend/src的绝对路径,确保跨平台兼容 const backendSrcAbsPath = path.resolve(__dirname, '../backend/src'); const pyshell = new PythonShell('../backend/src/functions/resource_logs.py', { env: { // 继承原有环境变量,避免覆盖其他配置 ...process.env, // 将backend/src加入PYTHONPATH,Windows和Unix系统用不同分隔符,path.delimiter自动处理 PYTHONPATH: backendSrcAbsPath + (process.env.PYTHONPATH ? path.delimiter + process.env.PYTHONPATH : '') } }); pyshell.on('message', (message) => { console.log(message); }); pyshell.end((err, code, signal) => { if (err) throw err; console.log('The exit code was: ' + code); console.log('The exit signal was: ' + signal); console.log('finished'); });
原理:PYTHONPATH是Python识别模块搜索路径的环境变量,设置后Python会自动从该路径下查找模块。
方案三:修改Python进程的工作目录(CWD)
将PythonShell的工作目录设置为backend/src,这样Python的模块搜索行为和直接运行脚本时一致:
const {PythonShell} = require('python-shell'); const path = require('path'); // 设置Python进程的工作目录为backend/src的绝对路径 const backendSrcCwd = path.resolve(__dirname, '../backend/src'); // 脚本路径改为相对于CWD的路径:functions/resource_logs.py const pyshell = new PythonShell('functions/resource_logs.py', { cwd: backendSrcCwd }); pyshell.on('message', (message) => { console.log(message); }); pyshell.end((err, code, signal) => { if (err) throw err; console.log('The exit code was: ' + code); console.log('The exit signal was: ' + signal); console.log('finished'); });
原理:直接运行Python脚本时,脚本所在目录会自动加入sys.path,将CWD设为backend/src后,Python会把当前工作目录加入搜索路径,从而找到同级的utils目录。
内容的提问来源于stack exchange,提问作者Harrison Floyd
相关产品推荐
相关产品推荐

