2013-10-16 18 views
6

我寫一個程序Go。在這個Go程序中,我想調用另一個文件中定義的Python函數並接收該函數的返回值,以便在Go程序的後續處理中使用它。儘管我在Go程序中返回任何返回的數據,但仍遇到問題。下面是什麼,我認爲會工作的最低例子,但顯然不會:調用從圍棋的Python功能和獲取函數的返回值

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我得到以下輸出:

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

的幾個注意事項:

  • 我使用-c國旗在Python中調用,所以我可以直接調用該函數cat_strings。假設cat_strings是一個Python文件的完整實用功能由其他的Python程序使用的一部分,因此爲什麼我沒有任何if __name__ == __main__業務。
  • 我不想修改Python的文件print a + b(而不是return a + b);請參閱先前關於函數是其他Python代碼應該可以調用的一組實用函數的一部分。
  • cat_strings功能是虛構和示範的目的;真正的功能是我不想簡單地在Go中重新實現的東西。我真的很感興趣,我可以從Go調用Python函數並獲取返回值。
+0

我有一種感覺,這不能輕易使用'OS/exec'完成。所有'os/exec'函數只返回stdout和/或stderr。 – Intermernet

+0

看看https://github.com/sbinet/go-python和http://stackoverflow.com/questions/12443203/writing-a-python-extension-in-go-golang – Intermernet

+0

@Intermernet我以爲我的在'python -c'中調用'print' import pythonfile;打印pythonfile.cat_strings(「foo」,「bar」)''將打印到標準輸出。 –

回答

8

我設法通過簡單地去掉引號周圍的命令本身有一些這方面的工作代碼:

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

果然,在source,你有這個功能(適用於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長度輸出。

+0

剛剛在Linux(Ubuntu)上測試並刪除單引號的作品,所以似乎是一個跨平臺的解決方案。 –

+4

不錯!樂於幫助。雖然正如其他人所建議的那樣,如果要大量使用它,最好使用CPython API綁定或使用網絡接口在Python和Go之間進行通信。 – val