17

我正在编写一个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")
}

蟒蛇文件.py

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

如果我打电话go run gofile,我会得到以下输出:

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

几点注意事项:

  • -c在 Python 调用中使用了标志,因此我可以直接调用该函数cat_strings。Assumecat_strings是一个 Python 文件的一部分,其中包含其他 Python 程序使用的实用函数,因此我没有任何if __name__ == __main__业务。
  • 我不想将 Python 文件修改为print a + b(而不是return a + b);请参阅关于该函数是一组实用函数的一部分的前一点,这些实用函数应该可以由其他 Python 代码调用。
  • cat_strings函数是虚构的,仅用于演示目的;真正的功能是我不想简单地在 Go 中重新实现的东西。我真的对如何从 Go 调用 Python 函数并获取返回值很感兴趣。
4

1 回答 1

17

通过简单地删除命令本身的引号,我设法获得了一些工作代码:

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。

于 2013-10-16T12:10:32.540 回答