好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > Golang如何調用Python代碼詳解

Golang如何調用Python代碼詳解

熱門標簽:高德地圖標注口訣 中國地圖標注省會高清 西部云谷一期地圖標注 南通如皋申請開通400電話 學海導航地圖標注 浙江高速公路地圖標注 地圖標注的汽車標 江西轉化率高的羿智云外呼系統 廣州呼叫中心外呼系統

前言

Python是時髦的機器學習御用開發語言,Golang是大紅大紫的新時代后端開發語言。Python很適合讓搞算法的寫寫模型,而Golang很適合提供API服務,兩位同志都紅的發紫,這里就介紹一下正確攪基的辦法。

go 中的 cgo 模塊可以讓 go 無縫調用 c 或者 c++ 的代碼,而 python 本身就是個 c 庫,自然也可以由 cgo 直接調用,前提是指定正確的編譯條件,如 Python.h 頭文件(),以及要鏈接的庫文件。本文以 Ubuntu 18.04 作為開發和運行平臺進行演示。

其實在使用 cgo 之前,筆者也考慮過使用 grpc 的方式。比如可以將需要調用的 python 代碼包裝成一個 grpc server 端,然后再使用 go 編寫對應的 client 端,這樣考慮的前提是,go 調用 python 代碼本來就是解一時之困,而且引入語言互操作后,對于項目維護和開發成本控制都有不小的影響,如果直接使用 grpc 生成編程語言無感知的協議文件,將來無論是重構或使用其他語言替換 python 代碼,都是更加方便,也是更加解耦的。所以 grpc 也是一種比較好的選擇。至于通信延遲,老實說既然已經設計語言互操作,本機中不到毫秒級的損失其實也是可以接受的。

接下來進入正題。

Golang調用Python代碼

1. 針對 python 版本安裝 python-dev

sudo apt install python3.6-dev

系統未默認安裝 python3.x 的開發環境,所以假如要通過 cgo 調用 python,需要安裝對應版本的開發包。

2. 指定對應的cgo CFLAGS 和 LDFLAGS 選項

對于未由 c 包裝的 python 代碼,python-dev 包中內置了 python-config 工具用于查看編譯選項。

python3.6-config --cflags

python3.6-config --ldflags

以下是對應的輸出

-I/usr/include/python3.6m -I/usr/include/python3.6m  -Wno-unused-result -Wsign-compare -g -fdebug-prefix-map=/build/python3.6-MtRqCA/python3.6-3.6.6=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O3 -Wall

-L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm  -xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

低版本的 python 也可以在安裝開發包后,使用對應的 python-config 命令打印依賴配置。由于 cgo 默認使用的編譯器不是 gcc ,所以輸出中的部分選項并不受支持,所以最后 cgo 代碼的配置為

//#cgo CFLAGS : -I./ -I/usr/include/python3.6m
//#cgo LDFLAGS: -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm
//#include "Python.h"
import "C"

3. 部分示例代碼

3.0 映射 PyObject

type PyObject struct {
 ptr *C.PyObject
}

func togo(obj *C.PyObject) *PyObject {
 if obj == nil {
  return nil
 }
 return PyObject{ptr: obj}
}

func topy(self *PyObject) *C.PyObject {
 if self == nil {
  return nil
 }
 return self.ptr
}

3.1 python 環境的啟動與終結

func Initialize() error {
 if C.Py_IsInitialized() == 0 {
  C.Py_Initialize()
 }
 if C.Py_IsInitialized() == 0 {
  return fmt.Errorf("python: could not initialize the python interpreter")
 }

 if C.PyEval_ThreadsInitialized() == 0 {
  C.PyEval_InitThreads()
 }
 if C.PyEval_ThreadsInitialized() == 0 {
  return fmt.Errorf("python: could not initialize the GIL")
 }

 return nil
}

func Finalize() error {
 C.Py_Finalize()
 return nil
}

3.2 包路徑與模塊導入

func InsertExtraPackageModule(dir string) *PyObject {
 sysModule := ImportModule("sys")
 path := sysModule.GetAttrString("path")

 cstr := C.CString(dir)
 defer C.free(unsafe.Pointer(cstr))
 C.PyList_Insert(topy(path), C.Py_ssize_t(0), topy(togo(C.PyBytes_FromString(cstr))))

 return ImportModule(dir)
}

func ImportModule(name string) *PyObject {
 c_name := C.CString(name)
 defer C.free(unsafe.Pointer(c_name))
 return togo(C.PyImport_ImportModule(c_name))
}

func (self *PyObject) GetAttrString(attr_name string) *PyObject {
 c_attr_name := C.CString(attr_name)
 defer C.free(unsafe.Pointer(c_attr_name))
 return togo(C.PyObject_GetAttrString(self.ptr, c_attr_name))
}

3.3 數據類型轉換

func PyStringFromGoString(v string) *PyObject {
 cstr := C.CString(v)
 defer C.free(unsafe.Pointer(cstr))
 return togo(C.PyBytes_FromString(cstr))
}

func PyStringAsGoString(self *PyObject) string {
 c_str := C.PyBytes_AsString(self.ptr)
 return C.GoString(c_str)
}

...

可以看到形似 C.Py* 的方法都是由 cgo 模塊編譯調用的,這些方法也是 python 暴露的C-API ,而這里的示例就到此為止,其他諸如調用 python 模塊方法的功能文檔里也描述得十分詳細,盡管實施起來仍然有些麻煩。

但是請注意 C-API 的 2.x 與 3.x 版本仍有不同,比如 2.x 版本中的字符串操作類型 PyString_* 在 3.x 中便被重命名為 PyBytes_* 。

關注過 go 與 python 互操作功能的同學應該注意到上述的示例代碼部分來自 go-python 這個開源項目,有興趣的同學也可以關注一下。 這個項目基于 python2.7 ,其中暴露的 api 諸如字符串轉換也是基于 python2.x 版本,所以針對于更流行的 python3.x 項目,大家就需要自己按照上文方法做一些修改了。

實際工作中,語言的互操作場景確實很讓人感覺頭疼,而 cgo 的文檔資料其實并不多,所以希望本文能給大家帶來一些幫助。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • python 調用API接口 獲取和解析 Json數據
  • python和js交互調用的方法
  • 通過實例解析Python調用json模塊
  • Python如何調用JS文件中的函數
  • json跨域調用python的方法詳解
  • Nodejs中調用系統命令、Shell腳本和Python腳本的方法和實例
  • python調用攝像頭的示例代碼
  • 使用C++調用Python代碼的方法詳解
  • 詳解C++調用Python腳本中的函數的實例代碼
  • Python調用JavaScript代碼的方法

標簽:吐魯番 常州 保定 許昌 東營 德宏 貴州 曲靖

巨人網絡通訊聲明:本文標題《Golang如何調用Python代碼詳解》,本文關鍵詞  Golang,如何,調用,Python,代碼,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Golang如何調用Python代碼詳解》相關的同類信息!
  • 本頁收集關于Golang如何調用Python代碼詳解的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 荆棘满途| 看黄a大片免费网站| 国产精品blacked在线| 美女的胸又www又黄的网站| BBBBB和BBBBBB的用法和作用| 手机在线播放免费1024| 波多野结衣电影| 亚洲欧美日韩国产精品26u | 国产毛片精品久久:| 日韩亚洲毛片无码不卡| 痴女勃起寸止榨干精在线播放 | 玉梅在厨房里被躁到高潮视频| 露阴图| 中文字幕人妻一区二区三区在线视频 | 国产精品久久久久精品电影影院| 大芭蕉欧美AAAA片视频网站| 日日射日日干| 学生的粉嫩小又紧水又多A片| 美女脱内衣禁止18以下免费见看| 啪啪下面流水的小黄文| 久久99亚洲精品久久99果冻| 日本美女裸体图片| 深夜福利在线视频| 美人娇贵| 无圣光国产精品一区| 16男男gaygays | 张柏芝艳照在线观看| 欧美精品videosbestsex日本| 国产精品手机视频| 最近中文字幕2019免费版2018| 母乳女上司| 日韩一区二区三区免费| 腹肌体育生自慰Chinese网站| 美女写真大尺度全真套图| 打美女屁屁嫩红gif动态图| 又大又硬又黄的免费视频| 国产AV精品亚洲八AV电影网站| 男女高清性高爱潮免费| 美女叉叉叉| 免费一级无码婬片A片AAA小说| 牝教师辱の教室在线|