Go调用Python by go-python3

确保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
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值