从Go调用Python函数并获取函数返回值 [英] Calling Python function from Go and getting the function return value

查看:1877
本文介绍了从Go调用Python函数并获取函数返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在撰写 Go 计划。在这个Go程序中,我想调用另一个文件中定义的Python函数,并接收该函数的返回值,以便在Go程序的后续处理中使用它。尽管我在Go程序中返回任何返回的数据,但仍遇到问题。以下是我认为可行的一个最低范例,但显然不是:

gofile.go

  package main 

importos / exec
importfmt

func main(){
fmt.Println(here we go ...)
program:=python
arg0:=-c
arg1:= fmt .Sprintf('import pythonfile; print pythonfile.cat_strings(\%s \,\%s\)',foo,bar)
cmd:= exec .Command(program,arg0,arg1)
fmt.Println(command args:,cmd.Args)
out,err:= cmd.CombinedOutput()
if err!= nil {
fmt.Println(串联失败,错误:,err.Error())
返回
}
fmt.Println(concatentation length:,len(out ))
fmt.Println(concatenation:,string(out))
fmt.Println(... done)
}

pythonfile.py

  def cat_string (a,b):
返回a + b

如果我调用 go run gofile 我得到以下输出:

 这里我们去... 
命令参数:[python -c'import pythonfile;打印pythonfile.cat_strings(foo,bar)']
concatentation length:0
concatenation:
... done

一些注释:


  • 我使用 -c 标志,所以我可以直接调用函数 cat_strings 。假设 cat_strings 是Python文件的一部分,其中包含了其他Python程序使用的实用函数,因此为什么我没有任何 if __name__ = = __main __ business。

  • 我不想将Python文件修改为 print a + b (而不是返回a + b );请参阅先前关于该函数是应由其他Python代码调用的一组实用函数的一部分的观点。

  • cat_strings 功能是虚构的,用于演示目的;真正的功能是我不想简单地在Go中重新实现的东西。我真的很感兴趣,我可以从Go调用Python函数并获得返回值。

      package main $ b 

    我设法通过删除命令本身的引用来获得一些工作代码。
    $ b importfmt
    importos / exec

    func main(){
    cmd:= exec.Command(python, - c,import pythonfile; print pythonfile.cat_strings('foo','bar'))
    fmt.Println(cmd.Args)
    out,err:= cmd.CombinedOutput()
    if err!= nil {fmt.Println(err); }
    fmt.Println(string(out))
    }

    足够的,在中,你有这个功能(对于Windows来说,至少我不知道如果适用于其他操作系统):

      // EscapeArg按照规定重写命令行参数s 
    // in http ://msdn.microsoft.com/en-us/library/ms880421。
    //如果s为空,则此函数返回(2个双引号)。
    //或者,这些转换已完成:
    // - 每个反斜杠(\)加倍,但仅限于立即
    //后跟双引号();
    // - 每个双引号()被斜杠(\)转义;
    // - 最后,s用双引号(arg - >arg),
    //包裹,但只有在s中有空格或制表符时才可以。
    func EscapeArg(s string)字符串{...

    所以你的代码结束了通过下面的命令行调用:

    $ $ $ $ $ $ $ $ $ $''$''import pythonfile; print pythonfile.cat_strings(\\ foo \\,\\\bar \\)'

    其中,如果测试,评估为一个字符串,并且不返回任何内容,因此为0长度输出。


    I am writing a Go program. From this Go program, I would like to call a Python function defined in another file and receive the function's return value so I can use it in subsequent processing in my Go program. I am having trouble getting any returned data back in my Go program though. Below is a minimum example of what I thought would work, but apparently doesn't:

    gofile.go

    package main
    
    import "os/exec"
    import "fmt"
    
    func main() {
         fmt.Println("here we go...")
         program := "python"
         arg0 := "-c"
         arg1 := fmt.Sprintf("'import pythonfile; print pythonfile.cat_strings(\"%s\", \"%s\")'", "foo", "bar")
         cmd := exec.Command(program, arg0, arg1)
         fmt.Println("command args:", cmd.Args)
         out, err := cmd.CombinedOutput()
         if err != nil {
             fmt.Println("Concatenation failed with error:", err.Error())
         return
         }
         fmt.Println("concatentation length: ", len(out))
         fmt.Println("concatenation: ", string(out))
         fmt.Println("...done")
    }
    

    pythonfile.py

    def cat_strings(a, b):
        return a + b
    

    If I call go run gofile I get the following output:

    here we go...
    command args: [python -c 'import pythonfile; print pythonfile.cat_strings("foo", "bar")']
    concatentation length:  0
    concatenation:  
    ...done
    

    A few notes:

    • I'm using the -c flag in the Python invocation so I can call the function cat_strings directly. Assume cat_strings is part of a Python file full of utility functions that are used by other Python programs, hence why I don't have any if __name__ == __main__ business.
    • I don't want to modify the Python file to print a + b (instead of return a + b); see the prior point about the function being part of a set of utility functions that ought to be callable by other Python code.
    • The cat_strings function is fictional and for demonstration purposes; the real function is something I don't want to simply reimplement in Go. I really am interested in how I can call a Python function from Go and get the return value.

    解决方案

    I managed to have some working code for this by simply removing the quote around the command itself:

    package main
    
    import "fmt"
    import "os/exec"
    
    func main() {
        cmd := exec.Command("python",  "-c", "import pythonfile; print pythonfile.cat_strings('foo', 'bar')")
        fmt.Println(cmd.Args)
        out, err := cmd.CombinedOutput()
        if err != nil { fmt.Println(err); }
        fmt.Println(string(out))
    }
    

    And sure enough, in the source, you have this function (for Windows, at least, I don't know if that works for other OSes):

    // EscapeArg rewrites command line argument s as prescribed
    // in http://msdn.microsoft.com/en-us/library/ms880421.
    // This function returns "" (2 double quotes) if s is empty.
    // Alternatively, these transformations are done:
    // - every back slash (\) is doubled, but only if immediately
    //   followed by double quote (");
    // - every double quote (") is escaped by back slash (\);
    // - finally, s is wrapped with double quotes (arg -> "arg"),
    //   but only if there is space or tab inside s.
    func EscapeArg(s string) string { ...
    

    So your code is ending up passing the following command line call:

    $ python -c "'import pythonfile; print pythonfile.cat_strings(\\"foo\\", \\"bar\\")'"
    

    Which, if tested, evaluates to a string and returns nothing, hence the 0-length output.

    这篇关于从Go调用Python函数并获取函数返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆