美文网首页Go
Golang 执行Python脚本

Golang 执行Python脚本

作者: 承诺一时的华丽 | 来源:发表于2019-04-25 09:43 被阅读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()
    }
    

    相关文章

      网友评论

        本文标题:Golang 执行Python脚本

        本文链接:https://www.haomeiwen.com/subject/fbaogqtx.html