dongwei4096
2013-10-16 07:56
浏览 482
已采纳

从Go调用Python函数并获取函数返回值

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.

图片转代码服务由CSDN问答提供 功能建议

我正在编写 继续程序。 从这个Go程序中,我想调用另一个文件中定义的Python函数并接收该函数的返回值,以便可以在Go程序的后续处理中使用它。 我在Go程序中无法获取任何返回的数据。 以下是我认为可行的最小示例,但显然不可行:

gofile.go

  包main 
 
import“ os / exec” 
import“ fmt” 
 
func main(){
 fmt.Println(“ here we go ...”)
 program:=“ python”  
 arg0:=“ -c” 
 arg1:= fmt.Sprintf(“'导入pythonfile;打印pythonfile.cat_strings(\”%s \“,\”%s \“)'”,“ foo”,“  bar“)
 cmd:= exec.Command(程序,arg0,arg1)
 fmt.Println(” command args:“,cmd.Args)
 out,err:= cmd.CombinedOutput()
如果出现错误 != nil {
 fmt.Println(“连接失败,并显示错误:”,err.Error())
返回
} 
 fmt.Println(“连接长度:”,len(out))
 fmt  .Println(“ concatenation:”,string(out))
 fmt.Println(“ ... done”)
} 
   
 
 

pythonfile .py

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

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

 我们去了... \  ncommand args:[python -c'import pythonfile; 打印pythonfile.cat_strings(“ foo”,“ bar”)'] 
连接长度:0 
连接:
 ...完成
   
 
 

一些注意事项:

  • 我在Python调用中使用了 -c 标志,因此我可以直接调用函数 cat_strings 。 假设 cat_strings 是一个Python文件的一部分,该文件包含其他Python程序使用的实用程序功能,因此为什么我没有任何 if __name__ == __main __ 业务。 / li>
  • 我不想修改Python文件以打印a + b (而不是 return a + b ); 请参阅关于该函数属于一组实用程序函数的一部分的先验知识,这些函数应该可以被其他Python代码调用。
  • cat_strings 函数是虚构的,仅供演示 ; 真正的功能是我不想简单地在Go中重新实现的功能。 我真的很感兴趣如何从Go调用Python函数并获取返回值。
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douhuan4699 2013-10-16 12:10
    已采纳

    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.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题