Golang 执行Python脚本
2019-04-25 本文已影响2人
承诺一时的华丽
一、两种方式
- 通过命令行的方式调用python脚本
- github.com/sbinet/go-python
二、实现
1、通过命令行的方式调用python脚本
在golang对jpg图片dpi操作未提供原生的相关接口,只好依赖python脚本达到想要的目的
main.py
from PIL import Image as ImagePIL, ImageFont, ImageDraw
import base64
import io
import sys
def main(argv):
msg="success"
try:
base64Str=argv[0]
savePath=argv[1]
xdpi=300.0
ydpi=300.0
argvLen=len(argv)
if argvLen>2:
xdpi=float(argv[2])
if argvLen>3:
xdpi=float(argv[3])
if base64Str=="":
msg="base64Str is empty"
return msg
if savePath=="":
savePath="savePath is empty"
return msg
f = open(base64Str)
base64Str=f.read()
f.close()
if base64Str.find(";base64,")>-1:
base64Str=base64Str[base64Str.find(";base64,")+8:len(base64Str)]
imgdata = base64.b64decode(base64Str)
image=io.BytesIO(imgdata)
img =ImagePIL.open(image)
img=img.convert('RGB')
img.save(savePath,dpi=(xdpi,ydpi))
img.close()
except Exception as result:
msg=result
finally:
return msg
if __name__ == '__main__':
msg=main(sys.argv[1:])
print(msg)
gopython_test.go
//执行python脚本
func CmdPythonSaveImageDpi(filePath, newFilePath string) (err error) {
args := []string{"main.py", filePath, newFilePath}
out, err := exec.Command("python", args...).Output()
if err != nil {
return
}
result := string(out)
if strings.Index(result, "success") != 0 {
err = errors.New(fmt.Sprintf("main.py error:%s", result))
}
return
}
//test测试
func TestCmdPython(t *testing.T) {
//test.txt的内容为图片的base64字符串
filePath := "test.txt"
newFileName := "test.jpg"
err :=CmdPythonSaveImageDpi(filePath,newFileName)
if err != nil {
t.Error(err)
return
}
t.Log("转换成功")
}
2、github.com/sbinet/go-python
使用Go 1和go工具,cgo包不能再CGO_CFLAGS从外部程序(除了pkg-config)传递到“假” #cgo预处理器指令。
go-python现在用于pkg-config获取标头和库的正确位置。遗憾的是,pkg-config程序包的命名约定在发行版和操作系统之间并未标准化,因此您可能必须相应地编辑该cgoflags.go文件。
- 安装go-python
go get github.com/sbinet/go-python
如果go get+ pkg-config失败:
$ cd go-python
$ edit cgoflags.go
$ make VERBOSE = 1
注意:您需要正确的标头和python开发环境。在Debian上,您需要安装该python-all-dev软件包
关于更多的安装问题:https://github.com/sbinet/go-python/issues/28
values.py
#!/usr/bin/env python2
sval = "42"
ival = 666
def myfunc():
return "sval='%s'\nival=%d" %(sval,ival)
main.go
package main
import (
"fmt"
"log"
"github.com/sbinet/go-python"
)
func init() {
err := python.Initialize()
if err != nil {
log.Panic(err.Error())
}
}
func main() {
module := python.PyImport_ImportModule("values")
if module == nil {
log.Fatal("could not import 'values'")
}
name := module.GetAttrString("__name__")
if name == nil {
log.Fatal("could not getattr '__name__'")
}
defer name.DecRef()
fmt.Printf("values.__name__: %q\n", python.PyString_AsString(name))
sval := module.GetAttrString("sval")
if sval == nil {
log.Fatal("could not getattr 'sval'")
}
defer sval.DecRef()
fmt.Printf("values.sval: %q\n", python.PyString_AsString(sval))
pyival := module.GetAttrString("ival")
if pyival == nil {
log.Fatal("could not getattr 'ival'")
}
defer pyival.DecRef()
ival := python.PyInt_AsLong(pyival)
fmt.Printf("values.ival: %d\n", ival)
myfunc := module.GetAttrString("myfunc")
if myfunc == nil {
log.Fatal("could not getattr 'myfunc'")
}
defer myfunc.DecRef()
o1 := myfunc.CallFunction()
if o1 == nil {
log.Fatal("could not call 'values.myfunc()'")
}
fmt.Printf("%s\n", python.PyString_AsString(o1))
o1.DecRef()
// modify 'test.ival' and 'test.sval'
{
pyival := python.PyInt_FromLong(ival + 1000)
module.SetAttrString("ival", pyival)
pyival.DecRef()
pysval := python.PyString_FromString(python.PyString_AsString(sval) + " is the answer")
module.SetAttrString("sval", pysval)
pysval.DecRef()
}
o2 := myfunc.CallFunction()
if o2 == nil {
log.Fatal("could not call 'values.myfunc()'")
}
fmt.Printf("%s\n", python.PyString_AsString(o2))
o2.DecRef()
}