确保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步:
- 初始化python环境
- 引入模块py对象
- 使用该模块的变量与函数
- 解析结果
- 销毁python3运行环境
main.go:
package main
import (
"fmt"
"os"
"github.com/datadog/go-python3"
)
func init() {
python3.Py_Initialize()
if !python3.Py_IsInitialized() {
fmt.Println("Error initializing the python interpreter")
os.Exit(1)
}
}
func main() {
p := "/Users/gxy/opt/anaconda3/envs/go_python/lib/python3.7/site-packages"
InsertBeforeSysPath(p)
hello := ImportModule("./hello", "hello")
helloRepr, err := pythonRepr(hello)
if err != nil {
panic(err)
}
fmt.Printf("[MODULE] repr(hello) = %s\n", helloRepr)
a := hello.GetAttrString("a")
aString, err := pythonRepr(a)
if err != nil {
panic(err)
}
fmt.Printf("[VARS] a = %#v\n", aString)
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))
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)
python3.Py_Finalize()
}
func InsertBeforeSysPath(p string) {
sysModule := python3.PyImport_ImportModule("sys")
path := sysModule.GetAttrString("path")
python3.PyList_Append(path, python3.PyUnicode_FromString(p))
}
func ImportModule(dir, name string) *python3.PyObject {
sysModule := python3.PyImport_ImportModule("sys")
path := sysModule.GetAttrString("path")
python3.PyList_Insert(path, 0, python3.PyUnicode_FromString(dir))
return python3.PyImport_ImportModule(name)
}
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
}
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(使用前将#替换为@)