简体   繁体   English

在 Jython 中自动处理/忽略 NameError

[英]Automatically handling / ignoring NameError in Jython

I have a setup where I execute jython scripts from a Java application.我有一个设置,我从 Java 应用程序执行 jython 脚本。 The java application feed the jython script with variables, coming from the command line, so that a user can write the following code in it's jython script: java 应用程序为 jython 脚本提供来自命令行的变量,以便用户可以在其 jython 脚本中编写以下代码:

print("Hello, %s" % foobar)

And will call the java program with this:并将调用 java 程序:

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

My java application parse the command-line, and create a variable of that name with the given value to give to the jython scripting environment to consume.我的 java 应用程序解析命令行,并使用给定值创建该名称的变量,以提供给 jython 脚本环境使用。 All is well so far.到目前为止一切都很好。

My issue is that when the user does not provide the foobar command-line parameter, I'd like to be able to easily provide a fallback in my script.我的问题是,当用户不提供foobar命令行参数时,我希望能够轻松地在我的脚本中提供回退。 For now, the user needs to write that sort of code to handle the situation where the foobar parameter is missing from the command-line:现在,用户需要编写这样的代码来处理命令行中缺少foobar参数的情况:

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

But this is cumbersome, especially if the number of parameters is growing.但这很麻烦,尤其是在参数数量不断增长的情况下。 Is there a way to handle that better from the script user point of view?从脚本用户的角度来看,有没有办法更好地处理这个问题?

I was thinking of catching the jython NameError in the Java code, initializing the variable causing the exception to a default value if the variable causing the exception "looks like" a parameter (adding a naming convention is OK), and restarting where the exception occurred.我正在考虑在 Java 代码中捕获 jython NameError ,如果导致异常的变量“看起来像”一个参数(添加命名约定是可以的),则将导致异常的变量初始化为默认值,然后在发生异常的地方重新启动. Alternatively, I can require the script user to write code such as this:或者,我可以要求脚本用户编写如下代码:

parameter(foobar, "some default value")

Or something equivalent.或等价的东西。

Well, this is one ugly workaround I found so far.好吧,这是我迄今为止发现的一种丑陋的解决方法。 Be careful , as this will call the script in loop many times, and is O(n^2).小心,因为这将多次循环调用脚本,并且是 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM