自动处理/忽略Jython中的NameError

问题描述 投票:0回答:1

我有一个设置,可以从Java应用程序执行jython脚本。 Java应用程序向jython脚本提供了来自命令行的变量,以便用户可以在其jython脚本中编写以下代码:

print("Hello, %s" % foobar)

并且将以此来调用Java程序:

$ java -jar myengine.jar script.py --foobar=baz
Hello, baz

我的Java应用程序解析命令行,并使用给定的值创建该名称的变量,以提供给jython脚本环境使用。到目前为止一切都很好。

我的问题是,当用户不提供foobar命令行参数时,我希望能够轻松地在脚本中提供后备。现在,用户需要编写这种代码来处理命令行中缺少foobar参数的情况:

try: foobar
except NameError: foobar = "some default value"

但这很麻烦,尤其是在参数数量不断增长的情况下。 是否有一种方法可以从脚本用户的角度更好地处理此问题?

我曾想在Java代码中捕获jython NameError,如果导致异常的变量“看起来像”参数,则将导致异常的变量初始化为默认值(添加命名约定就可以了,然后在发生异常。或者,我可以要求脚本用户编写如下代码:

parameter(foobar, "some default value")

或等效的东西。

java jython
1个回答
0
投票

嗯,这是我到目前为止发现的一个丑陋的解决方法。 请小心,因为这将多次循环调用脚本,并且为O(n ^ 2)。

private void callScriptLoop(String scriptfile) {
    PythonInterpreter pi = new PythonInterpreter();
    pi.set("env", someEnv);
    int nloop = 0;
    boolean shouldRestart;
    do {
        shouldRestart = false;
        try {
            pi.execfile(scriptfile);
        } catch (Throwable e) {
            if (e instanceof PyException) {
                PyException pe = (PyException) e;
                String typ = pe.type.toString();
                String val = pe.value.toString();
                Matcher m = Pattern.compile("^name '(.*)' is not defined")
                        .matcher(val);
                if (typ.equals("<type 'exceptions.NameError'>")
                        && m.find()) {
                    String varname = m.group(1);
                    pi.set(varname, Py.None);
                    System.out.println(
                            "Initializing missing parameter '"
                            + varname + "' to default value (None).");
                    shouldRestart = true;
                    nloop++;
                    if (nloop > 100)
                        throw new RuntimeException(
                                "NameError handler infinite loop detected: bailing-out.");
                }
            }
            if (!shouldRestart)
                throw e;
        }
    } while (shouldRestart);
}
© www.soinside.com 2019 - 2024. All rights reserved.