用Clojure调用Python

本篇博文只是探索中记录,别指望很优雅,能def的我绝不let。

1:添加此功能库

此功能通过clj-python库实现,此库的项目地址:https://github.com/clj-python/libpython-clj,另外这个库能够从python调用clojure(有很多限制哦)。

首先在project.clj中添加此依赖,版本号根据自动提示而定好了:

[clj-python/libpython-clj "2.017"]

然后需要配置里面,比如我在一个config文件中写如下的代码:

(ns clojure-study.config
  (:require [libpython-clj2.python :as py]))
;; 这是用anaconda搞的
(py/initialize! :python-executable "/other/soft/anaconda/envs/py3/bin/python3.9"
                :library-path "/other/soft/anaconda/envs/py3/lib/libpython3.9.so")

官方写的文档都是在anaconda中,其实venv看起来也行。这是调用的在anaconda的虚拟机中的python,这个反正只是配置个虚拟环境,其实不用虚拟机也能玩。
可以让project把其设置成为开始的命名控件,这样项目一启动,这个配置跟着设置完毕:

:repl-options {:init-ns clojure-study.config}

2:添加python的库

这需要将python的require加入到clojure中,假设我们下面都在with-python.clj中搞的:

(ns clojure-study.with-python
  (:require [libpython-clj2.require :refer [require-python]]))

要require下python的库,比如numpy,就是如下的样子:

(require-python '[numpy :as np])

OK,这下就可以用numpy这个python包搞事情了,比如:

(def test-ary (np/array [[1 2][3 4]]))

3:搞一下我们要用的muggle-ocr

添加muggle-ocr,指定用阿里的源

pip install muggle-ocr -i https://mirrors.aliyun.com/pypi/simple/

试一试吧:

(py/from-import muggle_ocr.sdk SDK) 
(require-python '[builtins :as python])
(require-python '[muggle_ocr])
(def sdk (SDK (py/py.- muggle_ocr/ModelType OCR)))
(def f (python/open "/other/project/python/data_analysis/files/code_image/xuji_code.png" "rb"))
(def b (py/py. f read))
(py/py. f close)
(py/py. sdk predict b)

OK,会返回个识别出的字符串,如例子中的是

=>"2379"

4:关于Clojure和Python的考量

①体积:能不用python就不用,因为一个env可能会很大,但是一个jar包会小很多。

②clojure基于JVM,可以一次编译随处运行,python只是语言跨平台,编译后的文件不能,所以用了python反而不能运行时跨平台了。

③速度:clojure可以线程级并行和并发。python还是进程级(因为GIL)。

④生态:Clojure的生态很棒,各种ide和编辑器功能都要好的多。python用lisp形式的二奶语言叫Hy,但是生态真的不好,最佳搭档是spacemacs,但是这个玩意竟然不能够补全包名之类的,还指定版本(最佳的是0.20.0)。Clojure的keyword比字符串做字典的key好受的多,最起码能补齐。

⑤lisp:惰性计算什么的python也可以实现,但是麻烦。

⑥anaconda-navigator:Clojure用java9高分屏已经解决,但是anaconda-navigator,还真是有没有放大都不合适。

这里用python是用一些clojure缺乏的特性,毕竟python的包实在太多了,用起来也简单。比如俺们例子里面的muggle_ocr,其实numpy、pandas啥的,有clojure下的incanter就够了,不够的时候也不提倡用这个玩意。

但是真的要完成,时间还很紧,只能说有这个东西“真香”。适用于python向lisp和clojure进阶的人。

5:总结

语句 作用
(:require [libpython-clj2.python :as py]) 引入了python
(:require [libpython-clj2.require :refer [require-python]]) 引入了python的require
(py/from-import muggle_ocr.sdk SDK) from muggle_ocr.sdk as SDK
(require-python '[builtins :as python]) 引入了内置函数,如可以python/open
py/py.- get了python属性
py/py. 调用了方法

其他的后续需要了再添加。

posted @ 2022-02-20 23:14  孙旭升  阅读(166)  评论(0编辑  收藏  举报