Golang 执行Python脚本

承诺一时的华丽 · · 9544 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、两种方式

  • 通过命令行的方式调用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()
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:承诺一时的华丽

查看原文:Golang 执行Python脚本

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

9544 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传