目的
Python調用Go的方法,Python有很多功能強悍又使用簡潔的庫。而新生軍Go的多核心利用率也是非常強悍的。當然這是明面上的優點。反正你有很多理由想要讓Python能夠調用Go的方法。
實驗場景
做一個功能:二維碼識別
Python里面其實有些庫是能夠做二維碼識別的。但是要是是依賴比較嚴重
,要不就是不支持Python3
。另外,發現Go里面有個開源的二維碼識別項目。這里就讓Python調用Go里面二維碼識別接口來完成本次實驗。
Go二維碼識別庫地址:https://github.com/tuotoo/qrcode
現將項目下載回來,刪除不必要的文件。放入一個測試用的二維碼圖片test.png
版本
- Python 3.6.4 :: Anaconda custom (x86_64)
- go version go1.9.6 darwin/amd64
目錄結構
├── LICENSE
├── README.md
├── example
│ ├── cpu-profile.prof
│ ├── groups
│ ├── main.go
│ └── test.png
├── qrcode.go
└── version.go
編寫Go文件
編輯example/main.go
,如下:
package main
import (
"C"
"fmt"
"os"
qrcode "qrcode-master"
)
//export qrcodeText
func qrcodeText() *C.char {
fi, err := os.Open("./test.png")
if !check(err) {
return C.CString("")
}
defer fi.Close()
qrcode.Debug = false
qrmatrix, err := qrcode.Decode(fi)
check(err)
retq := qrmatrix.Content
return C.CString(retq)
}
func check(err error) bool {
if err != nil {
fmt.Println(err)
}
return err == nil
}
func main() {}
需要特別注意的是,在方法
qrcodeText
上的注釋//export qrcodeText
一定要加,這應該是用來生成頭文件的。否則等會兒編譯動態鏈接庫不會生成*.h
文件
編譯動態鏈接庫
go build -buildmode=c-shared -o rqcode.so main.go
以上命令會在當前目錄生成 rqcode.so
、rqcode.h
兩個文件。
文件目錄如下:
├── example
│ ├── cpu-profile.prof
│ ├── groups
│ ├── main.go
│ ├── qrcode.py
│ ├── rqcode.h
│ ├── rqcode.so
│ └── test.png
├── qrcode.go
└── version.go
創建Python文件
在相同的目錄下創建qrcode.py
文件,內容如下:
from ctypes import cdll, c_char_p
# 加載動態鏈接庫
lib = cdll.LoadLibrary('rqcode.so')
# 配置輸入和輸出參數變量類型
lib.qrcodeText.argtypes = None
lib.qrcodeText.restype = c_char_p
# 調用方法
rest = lib.qrcodeText()
print(rest.decode('utf-8'))
開始測試
python qrcode.py
打印出二維碼內容:
https://github.com/tuotoo/qrcode
測試過程中發現,有些二維碼是無法識別的,所以這個Go的識別庫是不完整的。
總結
根據以上測試,可以發現,Python和Go其實可以很好的結合。我們可以用Python快速的實現自己的想法,真的遇到性能瓶頸的時候,用Go重寫這部分。當然了,這也是以前Python+C/C++的開發方式,只不過,將C/C++換成了Go。但是Go用起來比C/C++要好太多了,你們說呢?