Clojure Jython interop [英] Clojure Jython interop

查看:130
本文介绍了Clojure Jython interop的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有人试图在Clojure内调用Jython函数
,以及如何这样做。我有
没有使用Jython,但我想象Jython解释器可以
调用与任何其他java代码相同的方式,Python程序
可以在其中运行。然而我不知道如果是可能的
某种方式从Clojure调用单个python函数。像我说的,I
还没有尝试过,所以它可能实际上是直接和
显而易见。

I was wondering if anyone has tried somehow calling Jython functions from within Clojure, and how you went about doing this if so. I have not used Jython, but I would imagine the Jython interpreter can be invoked in the same way as any other java code, and Python programs can be run within it. However I wonder if it would be possible to somehow call individual python functions from Clojure. Like I said, I have not tried this yet, so it might actually be straightforward and obvious. I'm just wondering if anyone has tried doing this.

感谢,
Rob

Thanks, Rob

推荐答案

注意:我刚刚意识到,这个问题具体涉及从Clojure调用Jython函数,而不是关于构建一个完整的Jython- Clojure互操作解决方案...但是!我已经产生了一个小的写作对我的初步想法后者,我想这是合乎逻辑的下一步反正。我的意思是,如何使用有趣的Python包没有合理方便地访问Python类?编写Python函数来包装方法调用等是一个可能的想法...但是一个可怕的。

A note: I just realised that the question is specifically about calling Jython functions from Clojure and not about building a full-fledged Jython-Clojure interop solution... But! I've already produced a smallish write-up on my initial thoughts on the latter and I guess that's the logical next step anyway. I mean, how'd you go about using interesting Python packages without reasonably convenient access to Python classes? Writing Python functions to wrap method calls and the like is a possible idea... but rather a horrible one. So here goes anyway.

对于从Clojure中调用Jython执行的Python函数的基本调用,读取了这一点下面的第二段和代码片段。然后阅读其余的乐趣和意想不到的利润。

For basic calling of Jython-executed Python functions from Clojure read the second paragraph below this point and the code snippets. Then read the rest for fun and unanticipated profit.

我认为经验最初是远离无缝的...事实上,平滑的颠簸可能真的是一个皇家的痛苦。仍然,我有一个预感,实际上可以更容易,然后从Java调用Jython。只是一个长达€0.02从我...可能有人更有见识来了,告诉我,我不知道我在说什么。 ; - )

I think that the experience would initially be far from seamless... In fact, my prediction would be that smoothing out the bumps could really be a royal pain. Still, I have a hunch it could actually be easier then calling into Jython from Java. Just a longish €0.02 from me... May someone more knowledgeable come and show me I don't know what I'm talking about. ;-)

首先要注意的是Jython在自己的类中包装所有,所有类都来自 org .python.core.PyObject ,不打扰Python可调用项可调用 Runnable

The first thing to notice is that Jython wraps everything in its own classes, all deriving from org.python.core.PyObject, doesn't bother to make Python callables Callable or Runnable etc. This might actually not be too much of a problem with some multimethod / macro wrappers.

Python类可以从Java中使用,但是我的(可能有缺陷的)理解通常,当试图对Jython生成的Python类实例进行操作时,Java代码只能看到从Java基类或接口继承的方法...否则需要特殊格式的docstring(!)。以下是JythonWiki上的相关页面的链接。 (不知道它是如何是最新的。)很酷的是,显然一个 PyObjectDerived (用户定义的Python类的一个实例)可以被说服调用它的方法与给定的参数。

Python classes can be used from Java, but my (possibly flawed) understanding is that normally, when trying to act upon Jython-made instances of Python classes, Java code only sees the methods inherited from a Java base class or interface... Otherwise a specially formatted docstring (!) is required. Here's a link to the relevant page on the JythonWiki. (No idea how up-to-date it is.) The cool thing is, apparently a PyObjectDerived (an instance of a user-defined Python class) can be convinced to call its methods with the given arguments. So, with a dilligent wrapping effort, one might hope to be able to use somewhat bearable syntax to do it.

事实上,让我们看一些代码:

In fact, let's see some code:

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

好吧,东西被包裹。一个fun Clojuresque unwrapper:

Well, things are wrapped. A fun 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))

与上述对应:

(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 。前者需要适当数量的位置参数,应该已经由 PyObject s。我不知道如何传递关键字参数...虽然Jython以这种方式,所以必须有一种方法。

The functions: You can .__call__ them and you can ._jcall them. The latter option is somewhat more pleasing, as it accepts a Java array of regular Java objects, although it still returns a PyObject. The former takes an appropriate number of positional arguments which should already by PyObjects. I've no idea how to pass in keyword arguments... though Jython does that somehow, so there must be a way.

这是一个超基本的帮助器 ._ jcall -type调用:

Here's an ultra-basic helper for ._jcall-type calls:

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

您可以。 exec 一个包含 fact 的Python定义的字符串,然后执行(py-callfact10)获取#< PyInteger 5> 返回;解开如果你喜欢它。

You can .exec a string containing a Python definition of fact, then do (py-call "fact" 10) to get a #<PyInteger 5> back; unwrap if you feel like it.

等等...我不知道是什么:

And so on and so forth... What I don't know is:


  1. 需要什么样的努力才能使这个有用的

这篇关于Clojure Jython interop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆