在現代軟件開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇文章將從多個方面對Golang調用Python的方法和技術進行詳細的闡述。
一、Golang里的Python調用庫
在Golang中使用Python可以不經過外部系統調用,而是直接調用Python庫中的函數,這種方法會更加高效快捷。Golang提供了Cgo的方式來將C語言和Golang代碼連接起來,進而調用Python C API。另外Golang里也有PyBind庫來實現Python調用,但是它是用C++寫的。下面是一個例子:
package main
// #cgo CFLAGS: -I/usr/include/python2.7
// #cgo LDFLAGS: -lpython2.7
// #include <Python.h>
import "C"
func main() {
C.Py_Initialize()
defer C.Py_Finalize()
// 調用Python庫
var moduleName = C.CString("hello")
defer C.free(unsafe.Pointer(moduleName))
var module = C.PyImport_Import(moduleName)
if module == nil {
C.PyErr_Print()
return
}
defer C.Py_DECREF(module)
var func_name = C.CString("hello")
defer C.free(unsafe.Pointer(func_name))
var func = C.PyObject_GetAttrString(module, func_name)
defer C.Py_DECREF(func)
var args = C.PyTuple_New(0)
var result = C.PyObject_CallObject(func, args)
defer C.Py_DECREF(result)
}
需要在編譯時添加Cgo相關的標識來使得程序可以成功編譯和調用Python函數。
二、JSON通訊
Python和Golang都很好地支持了JSON序列化和反序列化。當Golang調用Python時,可以使用JSON進行數據交流。具體來說,Golang可以將數據序列化成JSON格式,然後通過標準的輸入流(stdin)流給Python,Python進程對JSON進行解析和數據處理,最後將結果序列化成JSON返回給Golang,Golang再進行反序列化得到最終結果。另一種方法是使用socket通訊,這種方法相對更加靈活。
下面給出一個使用JSON進行通訊的例子,其中Python腳本用於計算給定字符串的哈希值:
Golang代碼:
package main
import (
"encoding/json"
"fmt"
"os/exec"
)
type PythonResult struct {
Hash string `json:"hash"`
}
func main() {
input := "test"
data, err := json.Marshal(input)
if err != nil {
fmt.Println(err)
return
}
cmd := exec.Command("python3", "calculate_hash.py")
stdin, err := cmd.StdinPipe()
if err != nil {
fmt.Println(err)
return
}
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Println(err)
return
}
err = cmd.Start()
if err != nil {
fmt.Println(err)
return
}
_, err = stdin.Write(data)
if err != nil {
fmt.Println(err)
return
}
var result PythonResult
decoder := json.NewDecoder(stdout)
err = decoder.Decode(&result)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result.Hash)
}
Python代碼:
import sys
import json
import hashlib
if __name__ == '__main__':
data = sys.stdin.read()
md5 = hashlib.md5()
md5.update(data.encode('utf-8'))
sys.stdout.write(json.dumps({'hash': md5.hexdigest()}))
三、Python作為RESTful API
由於Python非常擅長於構建Web應用和API,因此我們可以利用Python編寫RESTful API,讓Golang調用。使用Flask作為Web框架,實現一個簡單的計算加法的API:
Python代碼:
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/add', methods=['POST'])
def add_two_numbers():
data = request.json
num_a = data.get('numA', 0)
num_b = data.get('numB', 0)
result = num_a + num_b
return jsonify({'result': result})
Golang代碼:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type AddRequest struct {
NumA int `json:"numA"`
NumB int `json:"numB"`
}
type AddResponse struct {
Result int `json:"result"`
}
func main() {
client := &http.Client{}
data, _ := json.Marshal(&AddRequest{NumA: 2, NumB: 3})
req, _ := http.NewRequest("POST", "http://localhost:5000/add", bytes.NewBuffer(data))
req.Header.Set("Content-Type", "application/json")
resp, _ := client.Do(req)
var result AddResponse
decoder := json.NewDecoder(resp.Body)
err := decoder.Decode(&result)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result.Result)
}
運行Flask應用之後,Golang就可以調用該RESTful API進行計算。
四、結語
本文介紹了幾種在Golang中調用Python的方法,包括直接調用Python庫、使用JSON進行通訊和Python作為RESTful API。這些方法可以極大地擴展Golang的能力,使得開發者可以更加方便地利用Python的生態系統和庫。
原創文章,作者:NFCQN,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/375449.html