Go调用Python by go-python3

2023-05-16

确保python版本为3.7

conda create go_python python=3.7
conda activate go_python 

确保python和go的架构一致

.mac中使用go的amd64版本也就是intel的x86
我的go_x86安装路径:/Users/gxy/sdk/go_x86_1.19
进入这个文件夹修改go执行文件名字,防止和本来的arm架构的go重名,并且提醒自己使用的go环境

cd go_x86_1.19/bin
mv go gox86

配置环境

vim ~/.bash_profile

在这里插入图片描述

source ~/.bash_profile

测试

  gox86 version

在这里插入图片描述

安装go-python3包

进入你的项目工程目录

export PKG_CONFIG_PATH=/Users/gxy/opt/anaconda3/envs/go_python/lib/pkgconfig
gox86 get github.com/datadog/go-python3 

调用自定义python

目录结构

在这里插入图片描述

测试的python文件 hello.py:

  a = 10
  def SayHello(xixi):
        return xixi + "haha"

go调用python的过程分为以下5步:

  1. 初始化python环境
  2. 引入模块py对象
  3. 使用该模块的变量与函数
  4. 解析结果
  5. 销毁python3运行环境

main.go:

 package main

  import (
      "fmt"
      "os"
      "github.com/datadog/go-python3"
  )

  func init() {
      // 1. 初始化python环境
      python3.Py_Initialize()
      if !python3.Py_IsInitialized() {
          fmt.Println("Error initializing the python interpreter")
          os.Exit(1)
      }
  }

  func main() {
      // 2. 设置本地python import 的路径
      p := "/Users/gxy/opt/anaconda3/envs/go_python/lib/python3.7/site-packages"
      InsertBeforeSysPath(p)
      // 3. 导入hello模块
      hello := ImportModule("./hello", "hello")
      // pyObject => string 解析结果
      helloRepr, err := pythonRepr(hello)
      if err != nil {
          panic(err)
      }
      fmt.Printf("[MODULE] repr(hello) = %s\n", helloRepr)
      // 4. 获取变量
      a := hello.GetAttrString("a")
      aString, err := pythonRepr(a)
      if err != nil {
          panic(err)
      }
      fmt.Printf("[VARS] a = %#v\n", aString)
      // 5. 获取函数方法
      SayHello := hello.GetAttrString("SayHello")
      // 设置调用的参数(一个元组)
      args := python3.PyTuple_New(1)                                        // 创建存储空间
      python3.PyTuple_SetItem(args, 0, python3.PyUnicode_FromString("gxy")) // 设置值
      res := SayHello.Call(args, python3.Py_None)                           // 调用
      fmt.Printf("[FUNC] res = %s\n", python3.PyUnicode_AsUTF8(res))
      // 6. 调用第三方库sklearn
      sklearn := hello.GetAttrString("sklearn")
      skVersion := sklearn.GetAttrString("__version__")
      sklearnRepr, err := pythonRepr(sklearn)
      if err != nil {
          panic(err)
      }
      skVersionRepr, err := pythonRepr(skVersion)
      if err != nil {
          panic(err)
      }
      fmt.Printf("[IMPORT] sklearn = %s\n", sklearnRepr)
      fmt.Printf("[IMPORT] sklearn version =  %s\n", skVersionRepr)
      // 7. 结束环境
      python3.Py_Finalize()
  }

  // InsertBeforeSysPath
  // @Description: 添加site-packages路径即包的查找路径
  // @param p
  func InsertBeforeSysPath(p string) {
      sysModule := python3.PyImport_ImportModule("sys")
      path := sysModule.GetAttrString("path")
      python3.PyList_Append(path, python3.PyUnicode_FromString(p))
  }

  // ImportModule
  // @Description: 倒入一个包
  // @param dir
  // @param name
  // @return *python3.PyObject
  func ImportModule(dir, name string) *python3.PyObject {
      sysModule := python3.PyImport_ImportModule("sys")                 // import sys
      path := sysModule.GetAttrString("path")                           // path = sys.path
      python3.PyList_Insert(path, 0, python3.PyUnicode_FromString(dir)) // path.insert(0, dir)
      return python3.PyImport_ImportModule(name)                        // return __import__(name)
  }

  // pythonRepr
  // @Description: PyObject转换为string
  // @param o
  // @return string
  // @return error
  func pythonRepr(o *python3.PyObject) (string, error) {
      if o == nil {
          return "", fmt.Errorf("object is nil")
      }
      s := o.Repr()
      if s == nil {
          python3.PyErr_Clear()
          return "", fmt.Errorf("failed to call Repr object method")
      }
      defer s.DecRef()

      return python3.PyUnicode_AsUTF8(s), nil
  }

  // PrintList
  // @Description: 输出一个List
  // @param list
  // @return error
  func PrintList(list *python3.PyObject) error {
      if exc := python3.PyErr_Occurred(); list == nil && exc != nil {
          return fmt.Errorf("Fail to create python list object")
      }
      defer list.DecRef()
      repr, err := pythonRepr(list)
      if err != nil {
          return fmt.Errorf("fail to get representation of object list")
      }
      fmt.Printf("python list: %s\n", repr)
      return nil
  }

进入main.go所在目录

 gox86 build main.go

设置一个@rpath即之前本地conda创建的库,否则会有路径问题

  install_name_tool -add_rpath /Users/gxy/opt/anaconda3/envs/go_python/lib ./main

运行可执行文件main,显示打印结果
在这里插入图片描述
结果是显示了,但报错,尝试更新golang.org/x/sys 扩展包,未果,暂未解决。

  fatal error:unexpected signal during runtime execution
  [signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x4657ece]
  runtime stack:
  runtime.throw({0x40bd656?, 0x42bf000?})
          /Users/gxy/sdk/go_x86_1.19/src/runtime/panic.go:1047 +0x5d fp=0x20846d160 sp=0x20846d130 pc=0x40343dd
  runtime.sigpanic()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/signal_unix.go:819 +0x369 fp=0x20846d1b0 sp=0x20846d160 pc=0x4048589
  goroutine 1 [syscall]:
  runtime.cgocall(0x40980f0, 0xc00005fe18)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/cgocall.go:158 +0x5c fp=0xc00005fdf0 sp=0xc00005fdb8 pc=0x4005c5c
  github.com/datadog/go-python3._Cfunc_PyObject_GetAttrString(0x0, 0x4321120)
          _cgo_gotypes.go:4440 +0x4d fp=0xc00005fe18 sp=0xc00005fdf0 pc=0x4092c8d
  github.com/datadog/go-python3.(*PyObject).GetAttrString.func2(0x4321120?, 0xb?)
          /Users/gxy/go/go_projects/src/github.com/datadog/go-python3/object.go:84 +0x4c fp=0xc00005fe58 sp=0xc00005fe18 pc=0x4093a0c
  github.com/datadog/go-python3.(*PyObject).GetAttrString(0x40d7ed0?, {0x40b7b5e?, 0x40b8794?})
          /Users/gxy/go/go_projects/src/github.com/datadog/go-python3/object.go:84 +0x6a fp=0xc00005fea0 sp=0xc00005fe58 pc=0x409394a
  main.main()
          /Users/gxy/go/go_projects/src/main.go:47 +0x24b fp=0xc00005ff80 sp=0xc00005fea0 pc=0x409516b
  runtime.main()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:250 +0x212 fp=0xc00005ffe0 sp=0xc00005ff80 pc=0x4036bf2
  runtime.goexit()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00005ffe8 sp=0xc00005ffe0 pc=0x4060681
  goroutine 2 [force gc (idle)]:
  runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:363 +0xd6 fp=0xc00004cfb0 sp=0xc00004cf90 pc=0x4036fb6
  runtime.goparkunlock(...)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:369
  runtime.forcegchelper()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:302 +0xad fp=0xc00004cfe0 sp=0xc00004cfb0 pc=0x4036e4d
  runtime.goexit()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004cfe8 sp=0xc00004cfe0 pc=0x4060681
  created by runtime.init.6
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:290 +0x25
  goroutine 3 [GC sweep wait]:
  runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:363 +0xd6 fp=0xc00004d790 sp=0xc00004d770 pc=0x4036fb6
  runtime.goparkunlock(...)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:369
  runtime.bgsweep(0x0?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgcsweep.go:278 +0x8e fp=0xc00004d7c8 sp=0xc00004d790 pc=0x402494e
  runtime.gcenable.func1()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgc.go:178 +0x26 fp=0xc00004d7e0 sp=0xc00004d7c8 pc=0x4019806
  runtime.goexit()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004d7e8 sp=0xc00004d7e0 pc=0x4060681
  created by runtime.gcenable
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgc.go:178 +0x6b
  goroutine 4 [GC scavenge wait]:
  runtime.gopark(0xc0000280e0?, 0x40d7948?, 0x1?, 0x0?, 0x0?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:363 +0xd6 fp=0xc00004df70 sp=0xc00004df50 pc=0x4036fb6
  runtime.goparkunlock(...)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:369
  runtime.(*scavengerState).park(0x4155440)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgcscavenge.go:389 +0x53 fp=0xc00004dfa0 sp=0xc00004df70 pc=0x40229f3
  runtime.bgscavenge(0x0?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgcscavenge.go:617 +0x45 fp=0xc00004dfc8 sp=0xc00004dfa0 pc=0x4022fc5
  runtime.gcenable.func2()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgc.go:179 +0x26 fp=0xc00004dfe0 sp=0xc00004dfc8 pc=0x40197a6
  runtime.goexit()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004dfe8 sp=0xc00004dfe0 pc=0x4060681
  created by runtime.gcenable
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mgc.go:179 +0xaa
  goroutine 5 [finalizer wait]:
  runtime.gopark(0x4155840?, 0xc000007860?, 0x0?, 0x0?, 0xc00004c770?)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:363 +0xd6 fp=0xc00004c628 sp=0xc00004c608 pc=0x4036fb6
  runtime.goparkunlock(...)
          /Users/gxy/sdk/go_x86_1.19/src/runtime/proc.go:369
  runtime.runfinq()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mfinal.go:180 +0x10f fp=0xc00004c7e0 sp=0xc00004c628 pc=0x401890f
  runtime.goexit()
          /Users/gxy/sdk/go_x86_1.19/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004c7e8 sp=0xc00004c7e0 pc=0x4060681
  created by runtime.createfing
          /Users/gxy/sdk/go_x86_1.19/src/runtime/mfinal.go:157 +0x45
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go调用Python by go-python3 的相关文章

随机推荐

  • 推荐10款简单好用的免费内网穿透工具

    前言 远程办公越来越普遍 xff0c 但是如何应对在外远程桌面控制公司电脑 远程公司内网办公系统 调阅公司文件资料 远程公司内网服务器是个问题 而解决方案其实很简单 xff0c 做内网穿透就可以突破局域网的限制 xff0c 轻松实现公网访问
  • Java支付宝沙箱环境支付,官方Demo远程调试【内网穿透】

    文章目录 1 下载当面付demo2 修改配置文件3 打包成web服务4 局域网测试5 内网穿透6 测试公网访问7 配置二级子域名8 测试使用固定二级子域名访问 在沙箱环境调试支付SDK的时候 xff0c 往往沙箱环境部署在本地 xff0c
  • opencv内存不足问题(OpenCV Error: Insufficient memory)

    最近在用opencv自带的函数haartraining训练分类器 xff0c 之前用的图片是20 20 xff0c 能训练出分类器 xff0c 后来换成了80 86 xff0c 就报错了 xff0c 报的错误是内存不足 xff0c 于是 x
  • ffmpeg 4.2.2 实现mp4转avi(修改官方remuxing例子)

    最近想把ffmpeg官方例子过一遍 xff0c 达到初步了解ffmpeg的目的 xff0c 本文只是给自己一个记录 xff0c 也是在网上没有找到一样的文章 xff0c 发出来供大家指点 直接使用官方demo xff0c 把mp4转换成av
  • 12.bss段的初始化

    12 bss段的初始化 在C代码 xff1a 有初始化全局的数据段 xff0c 局部的栈 xff0c malloc部分的堆 xff0c 未初始化的全局的bss段 从上面的编译的信息知道 xff1a Bss段的起始地址 xff1a 00010
  • pandas学习之df.rename()

    pandas学习之df rename df rename 用于更改行列的标签 xff0c 即行列的索引 可以传入一个字典或者一个函数 在数据预处理中 xff0c 比较常用 官方文档 xff1a DataFrame rename self m
  • java8操作两个集合List

    public static void main String args List lt String gt list1 61 new ArrayList lt String gt list1 add 34 1 34 list1 add 34
  • Atcoder AGC005 题解

    A STring 用类似括号匹配的方法搞一下即可 span class token macro property span class token directive keyword include span span class toke
  • CentOS-7安装桌面环境

    CentOS 7安装桌面环境 CentOS 7安装桌面环境 CentOS 7安装Server with GUI 设置为开机从桌面环境启动 yum y group install 39 Server with GUI 39 systemctl
  • [软件注册]Sublime 3 激活/注册码(key)

    偶然发现了一种sublime激活方式 使用的sublime3 1 1版本 亲试有效 Step1 配置 host文件 推荐使用 switchhost软件 可以快速变更host span class hljs number 127 0 span
  • 测试git能否连接github

    welcome to my blog 使用以下命令进行测试 ssh T git 64 github com 出现报错 ssh dispatch run fatal Connection to 13 250 177 223 port 22 S
  • vtk中实现3D模型(读取文件)

    xff08 xff09 VTK 坐标系统及空间变换 窗口 视图分割 mb5fed73533dfa9的技术博客 51CTO博客 VTK学习 xff08 三 xff09 VTK读取序列图像 灰信网 xff08 软件开发博客聚合 xff09 读取
  • centos中安装Python2.7

    转载于 xff1a 秋水逸冰 CentOS 6 8安装Python2 7 13 查看当前系统中的 Python 版本 python version 返回 Python 2 6 6 为正常 检查 CentOS 版本 cat etc redha
  • 安装tar.gz文件(无configure文件)

    如何安装tar gz文件 xff08 以webstorm为例 xff09 1 获取root权限并输入密码 xff1a su root 2 进入有该文件的目录下 xff08 以我的为例 xff0c 具体看你的文件在哪里 xff09 cd 下载
  • 游戏服务端框架之业务线程模型

    请求消息绑定线程策略的选择 在上一篇文章中 我们看到 消息是直接在网络框架的io线程中处理的 这样做有一个非常严重的缺陷 如果业务处理比较耗时 那么io线程接受消息的速度就会下降 严重影响io的吞吐量 典型的 我们应该另起线程池 专门用于异
  • 在WSL中使用GPU:WSL2 + Ubuntu 18.04 + CUDA + Gnome图形界面环境配置

    目录 引言1 确认Windows 10版本2 在Windows上安装WSL23 在Windows上安装CUDA on WSL驱动4 在WSL2中安装CUDA Toolkit3 测试CUDA是否能在WSL2中运作4 安装Gnome图形界面其他
  • Centos 开启路由转发实现全网互通

    只需在RouterSrv网关服务器上开启路由转发功能即可 root 64 RouterSrv vi etc sysctl conf net ipv4 ip forward 61 1 添加此行即可 root 64 localhost sysc
  • 虚拟机中配置外网环境

    文章目录 在虚拟机中配置外网环境 在虚拟机中配置外网环境 主机为 win10 xff0c 虚拟机中为 ubuntu 系统 xff0c 采用clash 1 xff0c 设置 Allow Lan xff0c 允许局域网访问 2 xff0c 虚拟
  • mysql 操作数据库(备份与恢复)

    一 直接把创建数据库的语句放到sql 文件中 xff1a php 写法 xff1a lt php mysql port 61 get mysql port cmd 61 US MYSQL BIN 34 mysql exe port 61 3
  • Go调用Python by go-python3

    确保python版本为3 7 conda create go python span class token assign left variable python span span class token operator 61 spa