Bootstrap

java执行python时脚本引用动态配置文件遇到的问题

java执行python时脚本引用动态配置文件遇到的问题

当使用java去执行python脚本的时候,有时候会根据不同的传入参数去导入不同的组件。如我会根据传入的json参数param.username,去指定不同用户的配置文件,例如

import importlib

def load_config(username_name):
    try:
        config_module = importlib.import_module(f'config_{username_name}')
        return config_module
    except ImportError:
        print(f"Error: Configuration module 'config-{username_name}' not found.")
        sys.exit(1)

如果直接使用控制台执行,其结果是正常的。

但若通过java使用jython-standalone工具去执行,如

public static PyObject callPythonByJson(String fileUrl, String method, PyObject pyObject) {
    PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.execfile(fileUrl);
    PyFunction pyFunction = interpreter.get(method, PyFunction.class);
    PyObject res = pyFunction.__call__(pyObject);
    interpreter.close();
    return res;
}

执行时会出现找不到模块的异常

ImportError: No module

按照网上的一些说法,是因为jython在执行时没有将脚本所在的目录添加到模块搜索路径中,因此找到的解决方案基本都是去获取脚本所在的目录,再将该目录添加到sys.path中

import sys
import os

# 获取脚本所在的目录
script_dir = os.path.dirname(os.path.abspath(__file__))

# 将脚本所在的目录添加到sys.path中
if script_dir not in sys.path:
    sys.path.append(script_dir)

如果大多人做到这里能够正常成功,那就没问题了。

但我的程序中还是出现了问题:

NameError: global name '__file__' is not defined

因此我需要换种方式去获取脚本的路径

import inspect

script_dir = inspect.getfile(inspect.currentframe())

此时拿到的script_dir是该脚本文件的路径(包括文件名)。

而我需要的只是它的目录路径而已。

由于我的文件名是固定格式:adapter.py

因此我只需要将后边的文件名裁切就ok了

script_dir = inspect.getfile(inspect.currentframe())[:-10]

最终的代码样例如下:

# -*- coding: UTF-8 -*-
import sys
import os
import importlib
import inspect

def main(params):
    
    username = params["username"] # 获取用户名
    config_name = "config_" + username; # 获取引入的模块名
    script_dir = inspect.getfile(inspect.currentframe())[:-10] # 获取当前脚本文件目录路径
    print(script_dir)
    sys.path.append(script_dir) # 将当前目录添加到sys.path,以便导入同一目录下的模块
    config_module = importlib.import_module(config_name) # # 导入同目录下的指定模块
    
;