go调用python

安装

  1. 安装python和go的环境,
  2. 在debian和ubuntu系统上,还要sudo apt install python-all-dev
  3. 安装sudo apt-get install pkg-config
  4. 安装go get github.com/sbinet/go-python
  5. 测试

根据这个教程测试了以下,发现可以得到相同的结果(根据教程我写的文件放在后面test.go)
https://www.jianshu.com/p/a49047a474e5

注意一点,就是导入当前目录,教程使用的是空字符串"", 我测试以后发现不行,就使用了绝对路径"/home/zhang/桌面/go-python",如果不导入python文件所在目录,是找不到python文件的。

如果这个教程里面的全部能测试成功,那么go调用python基本没有问题了

python绘图

想要在python中实现傅里叶变换,然后把结果绘图表示出来,需要安装对应的python库。

首先,需要依次安装numpy,scipy,matplotlib这三个库

为了在终端能够绘制显示出结果的图像,还需要安装两个软件:

  1. tk开发包: sudo apt-get install tk-dev
  2. Python的tk模块:sudo apt-get install python-tk

然后就可以测试了。

首先测试直接运行python代码能否成功fft并绘图:

编写好代码fft2.go(代码在最后),然后输入:

python fft2.go

成功绘图:
go调用python

下面测试用go调用python的fft函数

需要改写fft2.py,改写后的代码放在最后(fft.py)。编写main.go,在其中导入fft.py所在目录,然后就可以调用fft.py了(main.go放在最后)
运行,可以输出结果:
go调用python

使用笔记

下面是关于go-python这个包的使用笔记

go导包:m= python.PyImport_ImportModule("fib")
有了包以后就可以调用里面的函数,访问变量
访问变量: path:= m.GetAttrString("path")//访问b包中名叫path的变量,事实上返回的是一个python-list
获取python-list中的一个元素 item := python.PyList_GET_ITEM(path,i)//返回一个python-string
python-string转为string s:=python.PyString_AsString(item)

访问函数:fib:= m.GetAttrString("fib")//根据函数名,返回python-function
调用函数: out:=fib.CallFunction(python.PyInt_FromLong(10))//返回python-int
pyint转为int:python.PyInt_AsLong(out)

test.go

package main
import (
	"fmt"
	"github.com/sbinet/go-python"
	"os"
)
func init(){
	err:= python.Initialize()
	if err!=nil{
		panic(err.Error())
	}
}
func main1(){
	rc := python.Py_Main(os.Args)
	os.Exit(rc)
	//go run main.go --version
	//2.7.17
}
func main2(){
	m:= python.PyImport_ImportModule("sys")
	if m == nil{
		fmt.Println("import error")
	}
	path:= m.GetAttrString("path")
	if path ==nil{
		fmt.Println("get path error")
		return
	}
	size := python.PyList_GET_SIZE(path)
	for i:=0;i<size;i++{
		item := python.PyList_GET_ITEM(path,i)
		s:=python.PyString_AsString(item)
		fmt.Println(s)
	}
//打印path
	///usr/lib/python2.7
	///usr/lib/python2.7/plat-x86_64-linux-gnu
	///usr/lib/python2.7/lib-tk
	///usr/lib/python2.7/lib-old
	///usr/lib/python2.7/lib-dynload
	///home/zhang/.local/lib/python2.7/site-packages
	///usr/local/lib/python2.7/dist-packages
	///usr/lib/python2.7/dist-packages
}
func main(){
	m:= python.PyImport_ImportModule("sys")
	if m == nil{
		fmt.Println("import error")
	}
	path:= m.GetAttrString("path")
	if path ==nil{
		fmt.Println("get path error")
		return
	}
//python文件存放的路径
	curdir:=python.PyString_FromString("/home/zhang/桌面/go-python/set_path")
	err:=python.PyList_Insert(path,0,curdir)

	if err!=nil{
		print(err)
	}
	size := python.PyList_GET_SIZE(path)
	for i:=0;i<size;i++{
		item := python.PyList_GET_ITEM(path,i)
		s:=python.PyString_AsString(item)
		fmt.Println(s)
	}

	m= python.PyImport_ImportModule("fib")
	if m == nil{
		fmt.Println("import fib error")
		return
	}


	size = python.PyList_GET_SIZE(path)
	for i:=0;i<size;i++{
		item := python.PyList_GET_ITEM(path,i)
		s:=python.PyString_AsString(item)
		fmt.Println(s)
	}

	fib:= m.GetAttrString("fib")
	if fib ==nil{
		fmt.Println("get fib error")
		return
	}
	out:=fib.CallFunction(python.PyInt_FromLong(10))
	if out==nil{
		fmt.Println("call fib error")
		return
	}
	fmt.Printf("fib(%d) = %d\n",10,python.PyInt_AsLong(out))

}

fft2.py

# _*_ coding: utf-8 _*_	
import numpy as np
from scipy.fftpack import fft,ifft
import matplotlib.pyplot as plt



#采样点选择1400个,因为设置的信号频率分量最高为600赫兹,根据采样定理知采样频率要大于信号频率2倍,所以这里设置采样频率为1400赫兹(即一秒内有1400个采样点,一样意思的)
def fft_func():
    x=np.linspace(0,1,1400)

    #设置需要采样的信号,频率分量有180,390和600
    y=7*np.sin(2*np.pi*180*x) + 2.8*np.sin(2*np.pi*390*x)+5.1*np.sin(2*np.pi*600*x)

    yy=fft(y)      #快速傅里叶变换
    yreal = yy.real    # 获取实数部分
    yimag = yy.imag    # 获取虚数部分

    yf=abs(fft(y))    # 取绝对值
    yf1=abs(fft(y))/len(x)   #归一化处理
    yf2 = yf1[range(int(len(x)/2))] #由于对称性,只取一半区间

    xf = np.arange(len(y))  # 频率
    xf1 = xf
    xf2 = xf[range(int(len(x)/2))] #取一半区间


    plt.subplot(221)
    plt.plot(x[0:50],y[0:50])
    plt.title('Original wave')

    plt.subplot(222)
    plt.plot(xf,yf,'r')
    plt.title('FFT of Mixed wave(two sides frequency range)',fontsize=7,color='#7A378B') #注意这里的颜色可以查询颜色代码表

    plt.subplot(223)
    plt.plot(xf1,yf1,'g')
    plt.title('FFT of Mixed wave(normalization)',fontsize=9,color='r')

    plt.subplot(224)
    plt.plot(xf2,yf2,'b')
    plt.title('FFT of Mixed wave)',fontsize=10,color='#F08080')


    plt.show()
fft_func()


fft.py:

# _*_ coding: utf-8 _*_	
import numpy as np
from scipy.fftpack import fft,ifft
import matplotlib.pyplot as plt
import json
def fft_func(data):

    z=json.loads(data)

    y=np.array(z)

    yf1=abs(fft(y))/len(z)   #归一化处理

    yf2 = yf1[range(int(len(z)/2))] #由于对称性,只取一半区间

    yA = yf2.tolist()

    return str(yA)# 返回float的 list


main.go


package main

import (
	"encoding/json"
	"fmt"
	"github.com/sbinet/go-python"
)
func init(){
	err:= python.Initialize()
	if err!=nil{
		panic(err.Error())
	}

}
func main(){
	m:= python.PyImport_ImportModule("sys")
	if m == nil{
		fmt.Println("import error")
	}
	path:= m.GetAttrString("path")

	if path ==nil{
		fmt.Println("get path error")
		return
	}
	//python文件存放的路径
	curdir:=python.PyString_FromString("/home/zhang/桌面/go-python/fft")
	python.PyList_Insert(path,0,curdir)

	//和获取包
	m=python.PyImport_ImportModule("fft")

	if m ==nil{
		fmt.Println("import err")
	}


	fft_func := m.GetAttrString("fft_func")


	if fft_func==nil{
		fmt.Println("get fft_func error")
		return
	}
	raw:=[]int{1,1,1,1,1,1,1,1}
	//raw:=[]float64{1.0,1.0,2.3}
	//raw :=make(map[string][]int)
	//raw["data"]=[]int{1,2,3}
	byt,_:=json.Marshal(raw)
	str :=  string(byt)

	res := fft_func.CallFunction(python.PyString_FromString(str))
	if res ==nil{
		fmt.Println("call fft_func error")
		return
	}
	s:=python.PyString_AS_STRING(res)
	print(s)
}
上一篇:Python系列爬虫之实现地理信息可视化


下一篇:IE浏览器兼容性的痛苦