我正在编写Go程序。从这个Go程序中,我想调用另一个文件中定义的Python函数并接收该函数的返回值,以便可以在Go程序的后续处理中使用它。我在将所有返回的数据恢复到我的Go程序时遇到了麻烦。以下是我认为可行的最低示例,但显然无效:
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
如果我打电话,go run gofile我得到以下输出:
go run gofile
here we go... command args: [python -c 'import pythonfile; print pythonfile.cat_strings("foo", "bar")'] concatentation length: 0 concatenation: ...done
一些注意事项:
-c
cat_strings
if __name__ == __main__
print a + b
return a + b
通过删除命令本身周围的引号,我设法获得了一些有效的代码:
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)) }
可以肯定的是,在源代码中,您具有此功能(至少对于Windows,我不知道该功能是否适用于其他操作系统):
// 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 { ...
因此,您的代码最终将通过以下命令行调用:
$ python -c "'import pythonfile; print pythonfile.cat_strings(\\"foo\\", \\"bar\\")'"
如果经过测试,则结果为字符串,不返回任何内容,因此输出长度为0。