【问题标题】:Automatically handling / ignoring NameError in Jython在 Jython 中自动处理/忽略 NameError
【发布时间】:2023-04-05 21:51:01
【问题描述】:

我有一个从 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】:

    嗯,这是我迄今为止发现的一种丑陋的解决方法。 小心,因为这会多次循环调用脚本,并且是 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多