golang呼叫python實戰

2021-10-23 15:14:33 字數 3464 閱讀 5026

go-python

python提供了豐富的c-api。而c和go又可以通過cgo無縫整合。所以,直接通過golang呼叫libpython,就可以實現go調python的功能了。但是過程比較複雜,而go-python提供了針對cpython-2的c-api提供了native-binding能力,方便實現了go到python的呼叫。

但是目前,go-python只支援python2.7。

pkg-config

go-python使用pkg-config來獲取python的標頭檔案及庫資訊。

​ 一般來說,如果庫的標頭檔案不在/usr/include目錄中,那麼在編譯的時候需要用-i引數指定其路徑。由於同乙個庫在不同系統上可能位於不同的目錄下,使用者安裝庫的時候也可以將庫安裝在不同的目錄下,所以即使使用同乙個庫,由於庫的路徑的不同,造成了用-i引數指定的標頭檔案的路徑和在連線時使用-l引數指定lib庫的路徑都可能不同,其結果就是造成了編譯命令介面的不統一。pkg-config就是用來解決編譯連線介面不統一問題的乙個工具。

pkg-config的基本思想是通過庫提供的乙個.pc檔案獲得庫的各種必要資訊的,包括版本資訊、編譯和連線需要的引數等。這樣,不管庫檔案安裝在哪,通過庫對應的.pc檔案就可以準確定位,可以使用相同的編譯和連線命令,使得編譯和連線介面統一。

環境配置(mac為例)

1、本地找到python-2.7.pc檔案。如果沒有則建立乙個。特別注意,prefix要指定為python2.7的library路徑。

prefix=/system/library/frameworks/python.framework/versions/2.7

exec_prefix=pre

fixl

ibdi

r=libdir=

prefix

libd

ir=/lib

includedir=$/include

name: python

description: python library

requires:

version: 2.7

libs.private: -ldl -framework corefoundation

libs: -llib

dir−

lpyt

hon2.7cf

lags

:−i-lpython2.7 cflags: -i

libdir

−lpy

thon

2.7c

flag

s:−i

/python2.7

2、將python-2.7.pc路徑新增到環境變數$pkg_config_path中

3、驗證結果:pkg-config --cflags – python-2.7

-i/system/library/frameworks/python.framework/versions/2.7/include/python2.7

4、執行make verbose=1,第一次執行可能會提示go-python命令找不到。將gopath的bin路徑新增到環境變數$path即可。如下圖ut通過,說明配置成功了。

5、單獨執行test。需要新增下pythonpath環境變數,否則將匯入不了python包。

export pythonpath=.:$pythonpath

cd go-python/tests/kw-args

go run main.go

importing kwargs…

args=() kwds={}

args=() kwds=

樣例使用python的cpickle模組,通過 dumps將python物件序列化儲存到乙個字串變數中,通過loads從字串變數中載入python物件。

)// 初始化go-python

func init()

}func main()

dumps := pickle.getattrstring("dumps") //獲取dumps函式

if dumps == nil defer dumps.decref() //減少引用計數,釋放資源。

out := dumps.callfunctionobjargs("o", pystr)  //針對python字串進行dumps操作。

if out == nil

defer out.decref()

fmt.printf("cpickle.dumps(%s) = %q\n", gostr,

python.pystring_asstring(out),

)loads := pickle.getattrstring("loads") //獲取loads函式

if loads == nil

defer loads.decref()

out2 := loads.callfunctionobjargs(「o」, out) //將dumps結果重新loads

if out2 == nil

defer out2.decref()

fmt.printf("cpickle.loads(%q) = %q\n",

python.pystring_asstring(out),

python.pystring_asstring(out2),

)

}

機制簡介

整個go-python的核心在於處理pyobject跟golang型別的關係。在python內部,pyobject結構體用來儲存全部物件共同的資料成員,以及實現gc機制所須要的一些輔助欄位等,所以說pyobjectpython物件機制的基礎。

sequence.go: 處理了pyobject跟golang內建型別的轉換。典型的例如:pystring_fromstring是將golang string轉換為python string,即pyobject;pystring_asstring是將pyobject轉換為golang string。

object.go:關於pyobject的一些核心操作。例如:獲取函式物件getattr,及響應函式物件的呼叫callfunctionobjargs等。

其本質是對python c擴充套件的封裝。如下所示:

func (self *pyobject) getattr(attr_name *pyobject) *pyobject

注意事項:

所有的pyobject物件使用結束,需要主動呼叫decref,通過減少引用計數的方式釋放物件,否則會產生記憶體洩漏。

golang和python互相呼叫

python3 ctypes golang cgo 綜述golang和python之間,當前可以通過golang的cgo和python的ctypes,把golang物件和python物件分別轉換為c物件,從而通過編譯和呼叫c的動態連線庫,完成互動。python呼叫golang go 函式實現 pac...

Python實列 計時器呼叫

1.fout.py python中對於計時器的呼叫.顯示.from dummy threading import class fout this class contain some functions to display.defualt string wait.system is waiting...

Python實列 計時器呼叫

1.fout.py python中對於計時器的呼叫.顯示.from dummy threading import class fout this class contain some functions to display.defualt string wait.system is waiting...