注:
关于构建成熟的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>
返回如果你喜欢,就把它打开。
诸如此类。。。我不知道的是:
-
需要做什么样的努力才能使它足够有用,以便将有趣的Clojure代码与有趣的Python代码连接起来。
-