go语言调用python_从Go调用Python函数并获取函数返回值

1586010002-jmsa.png

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值