go语言调用python_Golang中调用Python3

2023-05-16

最近有一个项目需要在服务端调用Python3.7写的算法,网上找了一圈,发现两个库都使用cgo特性调用了Python的C-API:

针对Python2:https://github.com/sbinet/go-python​github.com

针对Python3:https://github.com/DataDog/go-python3​github.com

由于我这边的算法是Python3.7写的,自然使用go-python3这个库,安装方法也简单,使用下面的命令:

go get github.com/DataDog/go-python3

安装库时,可能会提示找不到python3.pc这个文件,这时可以先安装对应有dev包,用pyenv就可以安装,然后配置PKG_CONFIGPATH到对应的pkgconfig文件下,那里会有python3.pc。重新配置好PKG_CONFIG_PATH后,再执行go get命令应该就不会报错了。

参考命令如下:

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/Users/yourname/.pyenv/versions/3.7-dev/lib/pkgconfig/

Golang中调用Python3时,一定要注意设置包的查找路径,参考代码如下:

func ImportModule(dir, name string) *python3.PyObject {

sysModule := python3.PyImport_ImportModule("sys")

path := sysModule.GetAttrString("path")

python3.PyList_Insert(path, 0, python3.PyUnicode_FromString("/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages"))

python3.PyList_Insert(path, 0, python3.PyUnicode_FromString(dir)

return python3.PyImport_ImportModule(name)

}

上面函数直接对系统的PATH变量进行了配置,dir变量用来传入自定义的模块路径(自已写的算法包等等),name是算法包的名字。

正常的调用步骤为:python3.Py_Initialize()初始化调用环境;

引入模块;

GetAttrString()得到算法包;

配置传入参数,调用Call()执行算法;

解析算法返回的结果;

python3.Py_Finalize()销毁Python3运行环境。

这里给出示例代码如下:

func PyTest() {

python3.Py_Initialize()

if !python3.Py_IsInitialized() {

fmt.Println("Error initializing the python interpreter")

os.Exit(1)

}

v := ImportModule("/Users/yourname/Desktop/lab/pppython", "value_pp")

b := v.GetAttrString("estimate_pp")

fmt.Printf("[FUNC] b = %#v\n", b)

bArgs := python3.PyTuple_New(1)

python3.PyTuple_SetItem(bArgs, 0, python3.PyUnicode_FromString("/Users/yourname/Desktop/lab/pppython/srcdata/67.csv"))

re := b.Call(bArgs, python3.Py_None)

fmt.Println("IsCallable: ", python3.PyCallable_Check(b))

re1 := python3.PyTuple_GetItem(re, 0)

re2 := python3.PyTuple_GetItem(re, 1)

fmt.Println("re1:", python3.PyLong_AsLong(re1))

fmt.Println("re2:", python3.PyLong_AsLong(re2))

python3.Py_Finalize()

}

由于算法中返回多个值时对应的是Tuple,所以上面采用了PyTupleGetItem来得到相应的元素,但拿到这个值还不能直接输出使用,因为它还是PyObject类型,需要根据实际类型再调用As相关的函数进行一次转化后再输出,比如这里用的是pythone.PyLong_AsLong。

go-python3这个库的源码比较简单,可以直接查看,也可以对比https://docs.python.org/3.7/c-api/index.html去理解。这里写的是Python3的调用方法,至python2相关的可以参考GO语言中文网的一篇文章https://studygolang.com/articles/11155​studygolang.com

里面用的是go-python库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go语言调用python_Golang中调用Python3 的相关文章

随机推荐