激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Golang如何調用Python代碼詳解

Golang如何調用Python代碼詳解

2020-05-20 10:37白細胞 Golang

這篇文章主要給大家介紹了關于Golang如何調用Python代碼的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

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

?
1
sudo apt install python3.6-dev

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

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

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

?
1
2
3
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 環境的啟動與終結

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 包路徑與模塊導入

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 數據類型轉換

?
1
2
3
4
5
6
7
8
9
10
11
12
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 的文檔資料其實并不多,所以希望本文能給大家帶來一些幫助。

總結

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

原文鏈接:http://www.cnblogs.com/Wddpct/p/9784037.html

延伸 · 閱讀

精彩推薦
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
主站蜘蛛池模板: 欧美成网站 | 欧美一级二级毛片视频 | 色婷婷av一区二区三区久久 | 国产成人精品一区在线播放 | 猫咪av在线 | 久久成人激情视频 | 鲁丝一区二区二区四区 | a免费毛片 | 污黄视频在线播放 | 欧美aⅴ在线观看 | 欧美一级黄色录像片 | 九九热这里只有精品8 | 日韩视频一 | 一区二区三区四区高清视频 | 亚洲一区在线观看视频 | 欧美扩阴视频 | 欧美亚洲一级 | 欧美日韩在线中文字幕 | 91精品国| 成年人在线视频 | 小视频在线看 | 毛片三区| 中文字幕在线观看日韩 | 免费三级大片 | 2019中文字幕在线播放 | 久久久久久久久久美女 | wwwxxx免费视频 | 模特三级在线观看 | 日本aaa一级片| 亚州成人在线观看 | 高清成人在线 | 成人午夜视频在线观看免费 | 国产精品久久久久无码av | 久久超 | 欧美成人一区二区三区电影 | 精品久久久av | 一级毛片免费高清 | 久久久久久久久91 | 国产精品久久久久久久模特 | 国产成人高潮免费观看精品 | 国产91九色在线播放 |