用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. | 调用了方法 |
其他的后续需要了再添加。