简介

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-python使用pkg-config来获取python的头文件及库信息。

​ 一般来说,如果库的头文件不在/usr/include目录中,那么在编译的时候需要用-I参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下,用户安装库的时候也可以将库安装在不同的目录下,所以即使使用同一个库,由于库的路径的不同,造成了用-I参数指定的头文件的路径和在连接时使用-L参数指定lib库的路径都可能不同,其结果就是造成了编译命令界面的不统一。pkg-config就是用来解决编译连接界面不统一问题的一个工具。

pkg-config的基本思想是通过库提供的一个.pc文件获得库的各种必要信息的,包括版本信息、编译和连接需要的参数等。这样,不管库文件安装在哪,通过库对应的.pc文件就可以准确定位,可以使用相同的编译和连接命令,使得编译和连接界面统一。

环境配置(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),

)

}

机制简介

整个go-python的核心在于处理PyObject跟golang类型的关系。在Python内部,PyObject结构体用来保存全部对象共同的数据成员,以及实现GC机制所须要的一些辅助字段等,所以说PyObjectPython对象机制的基础。

sequence.go: 处理了PyObject跟golang内置类型的转换。典型的例如:PyString_FromString是将golang string转换为python string,即PyObject;PyString_AsString是将PyObject转换为golang string。

object.go:关于PyObject的一些核心操作。例如:获取函数对象GetAttr,及响应函数对象的调用CallFunctionObjArgs等。

其本质是对python C扩展的封装。如下所示:

func (self *PyObject) GetAttr(attr_name *PyObject) *PyObject {

return togo(C.PyObject_GetAttr(self.ptr, attr_name.ptr))

}

注意事项:

所有的PyObject对象使用结束,需要主动调用DecRef,通过减少引用计数的方式释放对象,否则会产生内存泄漏。

cpythonjavagolang_golang调用python实战-阿里云开发者社区相关推荐

  1. java代码调用python_java调用python代码-阿里云开发者社区

    同样的我们需要安装jython,具体的步骤如下: 2. 下载下来的jar包其实既是使用的时候需要引入的jar包,也是安装就jython的jar包.具体安装细节参照:https://wiki.pytho ...

  2. python树莓派编程 沃尔弗拉姆_《 Python树莓派编程》——3.3 Python入门-阿里云开发者社区...

    本节书摘来自华章出版社<Python树莓派编程>一书中的第3章,第3.3节,作者:[美]沃尔弗拉姆·多纳特(Wolfram Donat)著韩德强 等译,更多章节内容可以访问云栖社区&quo ...

  3. python编写程序 计算1_《Python程序设计》——第1章 计算与问题求解简介 1.1 计算与Python简介-阿里云开发者社区...

    本节书摘来自华章计算机<Python程序设计>一书中的第1章,第1.1节,作者:[美]戴维 I.施奈德(David I. Schneider)著,更多章节内容可以访问云栖社区"华 ...

  4. boost库 python_Boost.Python简介-阿里云开发者社区

    Boost.Python简单概括:是Boost库的一部分:用来在C++代码中调用python代码以及在Python代码中调用C++代码,并且避免用户直接操作指针. 简介 BoostPython库让C+ ...

  5. python闭包的应用场景_聊聊Python闭包-阿里云开发者社区

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  6. python的回收机制_Python垃圾回收机制【人生苦短,我用python】-阿里云开发者社区...

    现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式.自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐 ...

  7. python创建虚拟环境打包_用虚拟环境保存库文件--Python打包-阿里云开发者社区

    用虚拟环境保存库文件 如果你同时负责多个 Python 项目,或者想要轻松打包某个项目及其关联的库文件,再 或者你担心已安装的库之间可能有冲突,那么你可以安装一个 Python 虚拟环境来分而 治之. ...

  8. 卷积神经网络算法python实现_卷积神经网络概述及python实现-阿里云开发者社区...

    对于卷积神经网络(CNN)而言,相信很多读者并不陌生,该网络近年来在大多数领域都表现优异,尤其是在计算机视觉领域中.但是很多工作人员可能直接调用相关的深度学习工具箱搭建卷积神经网络模型,并不清楚其中具 ...

  9. a记录 mysql_[a]-和[a]相关的内容-阿里云开发者社区

    HDOJ 1202 The calculation of GPA Problem Description 每学期的期末,大家都会忙于计算自己的平均成绩,这个成绩对于评奖学金是直接有关的.国外大学都是计 ...

最新文章

  1. java之php、Android、JAVA、C# 3DES加密解密
  2. EZ430 Chronos 如何提高开发调试效率探讨
  3. [Github]watch和star的区别
  4. python自动化_Python自动化测试入门必读
  5. VS2010 加入OpenCV 提示 0xc000007b 的错误
  6. Linux负载均衡粘滞会话:IP_HASH Session(nosql mysql 文件共享系统 ) Cookie客户端加密识别用户
  7. JAVAWEB(笔记)
  8. oracle更换年,Oracle数据库更换服务器10分钟切换方案
  9. jQuery 源码系列(二)init 介绍
  10. 数据机房温湿度检测物联网以太网传感器解决方案
  11. unity3D游戏开发之iTween介绍和用法
  12. php 七牛云 视频加水印
  13. 《Real-Time Rendering 4th Edition》读书笔记--简单粗糙翻译 第六章 纹理 Texturing
  14. mel编程相较于c语言怎么样,MEL语言
  15. 简单三步 用Yolov5快速训练自己的数据集
  16. 华硕h410csm怎么开启_昂达h410主板装win7系统及bios设置教程(首发支持10代cpu)
  17. 每天干的啥?(2018.09)
  18. 神经网络的功能特点包括,神经网络的功能特点是
  19. vivado下ila文件的读取和显示
  20. JAVA byte 类型

热门文章

  1. 深度理解Java中的static
  2. strlen函数、length函数、size函数的区别
  3. css中的setProperty()方法的理解
  4. SQL 视图,存储过程锁住了解锁的方法——最简单的方法
  5. NOI2010全程日记
  6. IOS 初级开发入门教程(四)基础控件使用小练习
  7. 学生籍贯管理系统说明书
  8. Python的应用(一)
  9. outlook html格式 效果,outlook中以html格式回复邮件
  10. 分享Python采集100个jQuery代码,总有一款适合您