Mic*_*zyk 13
注意:我刚刚意识到问题是关于从Clojure调用Jython函数而不是构建一个完整的Jython-Clojure互操作解决方案......但是!我已经对我对后者的初步想法做了一个小小的写作,我想这无论如何都是合乎逻辑的下一步.我的意思是,如果没有合理方便地访问Python类,你如何使用有趣的Python包呢?编写Python函数来包装方法调用等是一个可能的想法...而是一个可怕的想法.无论如何,这里也是如此.
对于从Clojure执行Jython执行的Python函数的基本调用,请阅读此点下面的第二段和代码片段.然后阅读其余的有趣和意想不到的利润.
我认为这种体验最初远非无缝......实际上,我的预测是平滑颠簸可能真的是一种皇室般的痛苦.尽管如此,我还是预感到从Java调用Jython实际上更容易.离我只有0.02欧元......可能会有更多知识渊博的人来告诉我,我不知道我在说什么.;-)
首先要注意的事情是,Jython的包装都在自己的班级,都来自衍生org.python.core.PyObject,不打扰到使Python可调用Callable或Runnable等,这实际上可能不会是太大的问题的一些多方法/宏包装.
可以从Java使用Python类,但我的(可能有缺陷的)理解是,通常,当尝试对Jython制作的Python类实例进行操作时,Java代码只能看到从Java基类或接口继承的方法...否则需要特殊格式的docstring(!).这是JythonWiki上相关页面的链接.(不知道它是如何最新的.)很酷的是,显然是PyObjectDerived(用户定义的Python类的一个实例)可以说服用给定的参数调用它的方法.因此,通过冗长的包装工作,人们可能希望能够使用有些可忍受的语法来完成它.
实际上,让我们看一些代码:
;; a handy instance of PythonInterpreter...
(def python (org.python.util.PythonInterpreter.))
(.eval python "5")
; -> #<PyInteger 5>
Run Code Online (Sandbox Code Playgroud)
好吧,事情都被包裹了.一个有趣的Clojuresque unwrapper:
(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))
Run Code Online (Sandbox Code Playgroud)
与上述相对应:
(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))
Run Code Online (Sandbox Code Playgroud)
功能:你可以,.__call__他们可以._jcall.后一种选择有点令人愉悦,因为它接受常规Java对象的Java数组,尽管它仍然返回一个PyObject.前者采用适当数量的位置参数,这些参数应该已经是PyObjects.我不知道如何传递关键字参数......虽然Jython以某种方式做到了,所以必须有办法.
这是一个用于._jcall-type调用的超基本助手:
(defn py-call [pyf & args]
(apply (fn [pyf & args] (._jcall pyf (into-array args)))
(map #(if (string? %) (py-eval %) %)
(cons pyf args)))
Run Code Online (Sandbox Code Playgroud)
你可以.exec包含一个Python定义字符串fact,然后做(py-call "fact" 10)得到一个#<PyInteger 5>备用; 如果您愿意,请打开包装.
依此类推......我不知道的是:
| 归档时间: |
|
| 查看次数: |
2705 次 |
| 最近记录: |