代码之家  ›  专栏  ›  技术社区  ›  rplevy

Clojure Jython互操作

  •  13
  • rplevy  · 技术社区  · 16 年前

    我想知道是否有人试图调用Jython函数 没有使用Jython,但我想Jython解释器可以 以与任何其他java代码和Python程序相同的方式调用 可以在其中运行。然而,我想知道是否有可能 以某种方式从Clojure调用单个python函数。就像我说的,我

    谢谢 抢劫

    1 回复  |  直到 16 年前
        1
  •  13
  •   Michał Marczyk    16 年前

    注: 关于构建成熟的Jython Clojure互操作解决方案。。。但是我已经写了一篇关于我对后者最初想法的小文章,我想这是合乎逻辑的下一步。我的意思是,在不方便访问Python类的情况下,您是如何使用有趣的Python包的?编写Python函数来包装方法调用等是一个可能的想法。。。但这是一个相当可怕的问题。不管怎样,还是这样。

    对于Clojure中Jython执行的Python函数的基本调用,请阅读下面的第二段和代码片段。然后阅读其余部分,以获得乐趣和意想不到的收益。

    我认为最初的体验远不是天衣无缝的。。。事实上,我的预测是,消除颠簸可能真的是一种巨大的痛苦。尽管如此,我还是有一种预感,这实际上比从Java调用Jython更容易。只是我的一个长0.02。。。希望有更博学的人来告诉我我不知道我在说什么

    首先要注意的是Jython包装了 一切 org.python.core.PyObject ,不必费心制作Python可调用函数 Callable Runnable 对于某些多方法/宏包装器来说,这实际上可能不是什么大问题。

    Python类可以从Java中使用,但我(可能有缺陷)的理解是,通常,当试图对Jython创建的Python类实例执行操作时,Java代码只看到从Java基类或接口继承的方法。。。否则为特殊格式的docstring(!)是必需的。这里有一个链接到 relevant page PyObjectDerived (用户定义的Python类的实例)可以确信使用给定的参数调用其方法。因此,通过勤奋的包装工作,人们可能希望能够使用某种程度上可以接受的语法来完成这项工作。

    ;; a handy instance of PythonInterpreter...
    (def python (org.python.util.PythonInterpreter.))
    (.eval python "5")
    ; -> #<PyInteger 5>
    

    好吧,事情已经解决了。一个有趣的Clojurque展开器:

    (defmulti py-wrap class)
    ;; but let's not wrap if already a PyObject...
    (defmethod py-wrap org.python.core.PyObject [pyo] pyo)
    (defmethod py-wrap Integer [n] (org.python.core.PyInteger n))
    (defmethod py-wrap Long [n] (org.python.core.PyLong n))
    (defmethod py-wrap BigInteger [n] (org.python.core.PyLong n))
    (defmethod py-wrap String [s] (org.python.core.PyString s))
    

    以及上述文件的对应文件:

    (defmulti py-unwrap class)
    ;; if unsure, hope it's not a PyObject at all...
    (defmethod py-unwrap :default [x] x)
    (defmethod py-unwrap org.python.core.PyInteger [n] (.getValue n))
    (defmethod py-unwrap org.python.core.PyString [s] (.toString s))
    

    功能:你可以 .__call__ 他们和你可以 ._jcall 他们。后一个选项更令人愉快,因为它接受常规Java对象的Java数组,尽管它仍然返回 PyObject . 前者采用适当数量的位置参数,这些参数应该已经由 S我不知道如何传入关键字参数。。。虽然Jython不知怎么做到了,但一定有办法。

    这里有一个超基本的帮助 美国足球协会

    (defn py-call [pyf & args]
      (apply (fn [pyf & args] (._jcall pyf (into-array args)))
             (map #(if (string? %) (py-eval %) %)
                  (cons pyf args)))
    

    你可以 .exec 包含的Python定义的字符串 fact ,然后做 (py-call "fact" 10) 得到 #<PyInteger 5> 返回如果你喜欢,就把它打开。

    诸如此类。。。我不知道的是:

    1. 需要做什么样的努力才能使它足够有用,以便将有趣的Clojure代码与有趣的Python代码连接起来。