简介: # 简介 ## go-python Python提供了丰盛的[C-API](https://docs.python.org/2/c-a…。而C和Go又能够通过cgo无缝集成。所以,间接通过Golang调用libpython,就能够实现Go调Python的性能了。然而过程比较复杂,而[go-python](https://github.com/sbinet/go-…

简介

go-python

Python提供了丰盛的C-API。而C和Go又能够通过cgo无缝集成。所以,间接通过Golang调用libpython,就能够实现Go调Python的性能了。然而过程比较复杂,而go-python提供了针对CPython-2的C-API提供了native-binding能力,不便实现了Go到Python的调用。

然而目前,go-python只反对python2.7。

pkg-config

go-pythonpkg-config
pkg-config
pkg-config
环境配置(MAC为例)

1、本地找到python-2.7.pc文件。如果没有则创立一个。特地留神,prefix要指定为python2.7的library门路。

# See: man pkg-config
prefix=/System/Library/Frameworks/Python.framework/Versions/2.7
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Python
Description: Python library
Requires:
Version: 2.7
Libs.private: -ldl  -framework CoreFoundation
Libs: -L${libdir} -lpython2.7
Cflags: -I${includedir}/python2.7

2、将python-2.7.pc门路增加到环境变量$PKG_CONFIG_PATH中

3、验证后果:pkg-config –cflags — python-2.7
-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7

4、执行make VERBOSE=1,第一次执行可能会提醒go-python命令找不到。将gopath的bin门路增加到环境变量$PATH即可。如下图ut通过,阐明配置胜利了。

5、独自执行test。须要增加下PYTHONPATH环境变量,否则将导入不了python包。

export PYTHONPATH=.:$PYTHONPATH

cd go-python/tests/kw-args
go run main.go
importing kwargs...
args=() kwds={}
args=() kwds={'a': 3}
样例

应用python的cPickle模块,通过 dumps将python对象序列化保留到一个字符串变量中,通过loads从字符串变量中载入python对象。

package main

import (
    "fmt"
    "github.com/sbinet/go-python"
)

// 初始化go-python
func init() {
    err := python.Initialize()
    if err != nil {
        panic(err.Error())
    }
}

func main() {
    gostr := "foo"  //定义goloang字符串
    pystr := python.PyString_FromString(gostr)  //将golang字符串专程python字符串
    str := python.PyString_AsString(pystr)     //将python字符串,再转为golang字符串。
    fmt.Println("hello [", str, "]")

    pickle := python.PyImport_ImportModule("cPickle")  //导入cPickle模块
    if pickle == nil {
        panic("could not import 'cPickle'")
    }

    dumps := pickle.GetAttrString("dumps")   //获取dumps函数
    if dumps == nil {
        panic("could not retrieve 'cPickle.dumps'")
    }
  defer dumps.DecRef()   //缩小援用计数,开释资源。
    
    out := dumps.CallFunctionObjArgs("O", pystr)  //针对python字符串进行dumps操作。
    if out == nil {
        panic("could not dump pystr")
    }
  defer out.DecRef()    
 
    fmt.Printf("cPickle.dumps(%s) = %q\n", gostr,
        python.PyString_AsString(out),
    )
    
    loads := pickle.GetAttrString("loads")  //获取loads函数
    if loads == nil {
        panic("could not retrieve 'cPickle.loads'")
    }
  defer loads.DecRef()
    out2 := loads.CallFunctionObjArgs("O", out)  //将dumps后果从新loads
    if out2 == nil {
        panic("could not load back out")
    }
  defer out2.DecRef()

    fmt.Printf("cPickle.loads(%q) = %q\n",
        python.PyString_AsString(out),
        python.PyString_AsString(out2),
    )
}
机制简介
PyObjectPyObjectPyObject
PyObject
func (self *PyObject) GetAttr(attr_name *PyObject) *PyObject {
    return togo(C.PyObject_GetAttr(self.ptr, attr_name.ptr))
}

注意事项:

所有的PyObject对象应用完结,须要被动调用DecRef,通过缩小援用计数的形式开释对象,否则会产生内存透露。

原文链接
本文为阿里云原创内容,未经容许不得转载。