Llamar a la función Python desde Go y obtener el valor de retorno de la función

Estoy escribiendo un progtwig Go . Desde este progtwig Go, me gustaría llamar a una función de Python definida en otro archivo y recibir el valor de retorno de la función para poder usarla en el procesamiento posterior de mi progtwig Go. Sin embargo, estoy teniendo problemas para recuperar los datos devueltos en mi progtwig Go. A continuación se muestra un ejemplo mínimo de lo que pensé que funcionaría, pero aparentemente no:

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 

Si llamo a go run gofile obtengo el siguiente resultado:

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

Algunas notas:

    • Estoy usando la -c en la invocación de Python para poder llamar directamente a la función cat_strings . Supongamos que cat_strings es parte de un archivo de Python lleno de funciones de utilidad que son utilizadas por otros progtwigs de Python, por lo tanto, no tengo ninguna if __name__ == __main__ business.
    • No quiero modificar el archivo de Python para print a + b (en lugar de return a + b ); vea el punto anterior sobre la función que forma parte de un conjunto de funciones de utilidad que deberían ser invocadas por otro código Python.
    • La función cat_strings es ficticia y con fines de demostración; La función real es algo que no quiero simplemente volver a implementar en Go. Realmente estoy interesado en cómo puedo llamar a una función de Python desde Go y obtener el valor de retorno.

    Logré tener un código de trabajo para esto simplemente eliminando la cita alrededor del comando en sí:

     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)) } 

    Y efectivamente, en la fuente , tiene esta función (para Windows, al menos, no sé si eso funciona para otros sistemas operativos):

     // 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 { ... 

    Entonces su código está terminando de pasar la siguiente llamada de línea de comando:

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

    Que, si se prueba, se evalúa como una cadena y no devuelve nada, por lo tanto, la salida de longitud 0.