当前位置: 首页 > news >正文

python和go相互调用的两种方法

前言

在这里插入图片描述

Python 和 Go 语言是两种不同的编程语言,它们分别有自己的优势和适用场景。在一些项目中,由于团队内已有的技术栈或者某一部分业务的需求,可能需要 Python 和 Go 相互调用,以此来提升效率和性能。

  • 性能优势

    Go 通常比 Python 更高效,尤其是在并发和并行处理方面。因此,可以使用 Go 编写高性能的底层组件或服务,并通过 Python 调用这些组件来提高整体性能。

  • 并发和并行处理

    Go 是为并发设计的语言,具有轻量级线程(goroutines)和通道(channels)等特性。在需要处理大量并发任务的情况下,Go 的并发性能可能优于 Python。通过将 Go 组件嵌入到 Python 代码中,可以利用 Go 的并发处理能力。

  • 易用性和灵活性

    Python 具有简洁、易读、易学的语法,适用于快速开发和原型设计。将 Python 用于高层逻辑和算法,而使用 Go 来编写性能敏感的底层组件,可以在性能和开发速度之间找到平衡。

方案简介

1.动态库调用

一、调用步骤:

将go代码编译成so库 -> python中通过ctypes引用so库并指定需要调用的函数(同时可指定传入参数类型和返回值类型) -> 指定后按python使用函数方式调用。

需要注意的是:python和go之间参数传递是需要经过C的数据类型转换的,因此需要了解python中ctypes数据类型和python数据类型以及C的数据类型对应关系

三种数据类型使用场景:

  1. ctypes数据类型为指定调用函数时的传入参数和返回值的数据类型
  2. python数据类型为调用函数时传入的参数的数据类型
  3. C的数据类型为go代码中定义的函数所需的参数和返回值数据类型

二、示例

假设我们就有这么一个函数,需要在 Python 中调用这个函数

func add(a int, b int) int {return a + b
}

第一步:对此函数进行改造
如下:

// main.go
package main
​
import "C"func main() {}//export add
func add(a int, b int) int {return a + b
}

1.import “C” 这个必须要加载 Go 源文件前,这一点必须做,应该就是告诉编译器我要即将编译的软件需要做为 C 的库而不直接是二进制。这个包也提供一些功能让 Go 去直接操作 C 的数据结构等等。
2.main() main 函数一定不能少,即使没有任何一行代码也没事;
3.//export add 在函数定义之前添加上注释来告诉编译器哪些定义可以被 C 引用,注意 // 和 export 之前不能有空格,否则会导出失败的

第二步: 将 Go 编译成 C 可以调用的库

执行命令

go build --buildmode=c-shared -o library.so main.go

编译完后在当前目录下回有一个 library.so 和 library.h 的文件

第三步:python调用

编写python调用函数main.py

import ctypeslib = ctypes.cdll.LoadLibrary("library.so")print(lib.add(1, 2))

由于Python和Go是两种不同的语言,其参数的类型也有所不同。所以在调用时需要进一步转换成C语言类型来进行转换。

import ctypeslib = ctypes.cdll.LoadLibrary("library.so")GoInt64 = ctypes.c_int64
GoInt = GoInt64add = lib.addadd.argtypes = [GoInt64, GoInt64]
add.restype = GoInt64res = add(GoInt(1), GoInt(2))print(res)

使用 ctypes.cdll.LoadLibrary 来加载这个动态库,然后就可以直接调用了。

其对应参数类型如下:
在这里插入图片描述
例如:当python传入的参数需是string时,ctypes中指定的传参参数类型需为c_wchar_p,go中需要指定接收的参数数据类型为 *C.wchar_t。

其他类型请参考文档链接https://docs.python.org/3.5/library/ctypes.html

2.grpc调用

在这里插入图片描述

grpc已经在之前文章https://blog.csdn.net/qq_45066628/article/details/118602349介绍过了,就不重复赘述了。

调用流程

Python gRPC
  1. 环境安装

    grpcio 是启动 gRPC 服务的项目依赖

    pip install grpcio

    grpcio 是启动 gRPC 服务的项目依赖

    pip install grpcio-tools

  2. 定义 proto 文件

    syntax = "proto3";import "google/protobuf/empty.proto";// service 关键字定义提供的服务
    service MyService {// 定义一个探活方法rpc Health (.google.protobuf.Empty) returns (.google.protobuf.Empty){}// 定义一个批量查询 user 的方法rpc User (UserReq) returns (UserReply){}}// message 关键字定义交互的数据结构
    message UserReq {repeated int32 userIDs= 1;
    }message UserReply {string message = 1;// repeated 定义一个数组repeated User data = 2;
    }message User {string name = 1;int32 age = 2;string email = 3;
    }
  3. 编译生成代码

    使用 protoc 和相应的插件可以编译生成对应语言的代码
    -I 指定 import 路径,可以指定多个 -I 参数,编译时按顺序查找,不指定默认当前目录

    python -m grpc_tools.protoc -I ./ --python_out=. --grpc_python_out=. ./api.proto

    经过上述步骤,我们生成了这样两个文件api_pb2.py 此文件包含每个 message 生成一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类api_pb2_grpc.py 此文件包含生成的 客户端(MyServiceStub)和服务端 (MyServiceServicer)的类。

  4. 实现python服务端

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    import logging
    from concurrent import futuresimport grpc
    from api import api_pb2_grpc, api_pb2
    from api.api_pb2_grpc import MyServiceServicer
    from service import get_usersclass Service(MyServiceServicer):def Health(self, request, context):returndef User(self, request, context):print('start to process request...')res = get_users(request.userIDs)users = []for u in res:users.append(api_pb2.User(name=u['name'], age=u['age'], email=u['email']))return api_pb2.UserReply(message='success', data=users)def serve():print('start grpc server====>')server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))api_pb2_grpc.add_MyServiceServicer_to_server(Service(), server)server.add_insecure_port('[::]:50051')server.start()server.wait_for_termination()if __name__ == '__main__':logging.basicConfig()serve()
Go gRPC

Go 服务作为客户端调用 Python 服务,同样需要根据 proto 文件生成代码,进而创建客户端发起 RPC。

  1. 环境搭建
    安装 ptotobuf, 推荐使用 brew

    brew install protobuf

    protoc go 插件安装

    go get -u github.com/golang/protobuf/protoc-gen-go

    这里安装在 GOPATH 下的 bin 目录,所以保证这个目录在 $PATH 中

    export PATH=“ P A T H : PATH: PATH:(go env GOPATH)/bin”

    代码 gprc 依赖安装

    go get -u google.golang.org/grpc

  2. 生成 Go pb 代码

    protoc -I ./ --go_out=plugins=grpc:./ api.proto

  3. Go客户端调用

    package mainimport ("context""fmt""log""time""ginDemo/api""google.golang.org/grpc"
    )const (address     = "localhost:50051"defaultName = "world"
    )func main() {conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := api.NewMyServiceClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()r, err := c.User(ctx, &api.UserReq{UserIDs: []int32{1, 2}})if err != nil {log.Fatalf("could not greet: %v", err)}fmt.Printf("gprc result: %+v", r.Data)
    }

相关文章:

python和go相互调用的两种方法

前言 Python 和 Go 语言是两种不同的编程语言,它们分别有自己的优势和适用场景。在一些项目中,由于团队内已有的技术栈或者某一部分业务的需求,可能需要 Python 和 Go 相互调用,以此来提升效率和性能。 性能优势 Go 通常比 Python 更高效&…...

c# 分部视图笔记

Html.Partial("**", 1) public ActionResult **(int page) { ViewBag.page page; return PartialView("**"); }...

Vue3最佳实践 第七章 TypeScript 中

Vue组件中TypeScript 在Vue组件中,我们可以使用TypeScript进行各种类型的设置,包括props、Reactive和ref等。下面,让我们详细地探讨一下这些设置。 设置描述设置props在Vue中,props本身就具有类型设定的功能。但如果你希望使用Ty…...

(三)行为模式:8、状态模式(State Pattern)(C++示例)

目录 1、状态模式(State Pattern)含义 2、状态模式的UML图学习 3、状态模式的应用场景 4、状态模式的优缺点 (1)优点 (2)缺点 5、C实现状态模式的实例 1、状态模式(State Pattern&#x…...

nginx的配置文件概述及简单demo(二)

默认配置文件 当安装完nginx后,它的目录下通常有默认的配置文件 #user nobody; worker_processes 1;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connection…...

Apollo Planning2.0决策规划算法代码详细解析 (2): vscode gdb单步调试环境搭建

前言: apollo planning2.0 在新版本中在降低学习和二次开发成本上进行了一些重要的优化,重要的优化有接口优化、task插件化、配置参数改造等。 GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端…...

flex 布局:元素/文字靠右

前言 略 使用flex的justify-content属性控制元素的摆放位置 靠右 <view class"more">展开更多<text class"iconfont20231007 icon-zhankai"></text></view>.more {display: flex;flex-direction: row;color: #636363;justify-co…...

java基础-第1章-走进java世界

一、计算机基础知识 常用的DOS命令 二、计算机语言介绍 三、Java语言概述 四、Java环境的搭建 JDK安装图解 环境变量的配置 配置环境变量意义 配置环境变量步骤 五、第一个Java程序 编写Java源程序 编译Java源文件 运行Java程序 六、Java语言运行机制 核心机制—Java虚拟机 核…...

jvm 堆内存 栈内存 大小设置

4种方式配置不同作用域的jvm的堆栈内存。 1、Eclise 中设置jvm内存: 改动eclipse的配置文件,对全部project都起作用 改动eclipse根文件夹下的eclipse.ini文件 -vmargs //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn16m //最小内存 -XX:PermSize=128M //非堆内…...

免杀对抗-反沙盒+反调试

反VT-沙盒检测-Go&Python 介绍&#xff1a; 近年来&#xff0c;各类恶意软件层出不穷&#xff0c;反病毒软件也更新了各种检测方案以提高检率。 其中比较有效的方案是动态沙箱检测技术&#xff0c;即通过在沙箱中运行程序并观察程序行为来判断程序是否为恶意程序。简单来说…...

QTimer类的使用方法

本文介绍QTimer类的使用方法。 1.单次触发 在某些情况下&#xff0c;定时器只运行一次&#xff0c;可使用单次触发方式。 QTimer *timer new QTimer(this); connect(timer, &QTimer::timeout, this, &MainWindow::timeout); timer->setSingleShot(true); timer-…...

(三)行为模式:9、空对象模式(Null Object Pattern)(C++示例)

目录 1、空对象模式&#xff08;Null Object Pattern&#xff09;含义 2、空对象模式的主要涉及以下几个角色 3、空对象模式的应用场景 4、空对象模式的优缺点 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 5、C实现空对象模式的实例 1、空对象模式&am…...

Django实战项目-学习任务系统-用户登录

第一步&#xff1a;先创建一个Django应用程序框架代码 1&#xff0c;先创建一个Django项目 django-admin startproject mysite将创建一个目录&#xff0c;其布局如下&#xff1a;mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.py 2&#xff0c;再创建一个…...

【动手学深度学习-Pytorch版】Transformer代码总结

本文是纯纯的撸代码讲解&#xff0c;没有任何Transformer的基础内容~ 是从0榨干Transformer代码系列&#xff0c;借用的是李沐老师上课时讲解的代码。 本文是根据每个模块的实现过程来进行讲解的。如果您想获取关于Transformer具体的实现细节&#xff08;不含代码&#xff09;可…...

做外贸独立站选Shopify还是WordPress?

现在确实会有很多新人想做独立站&#xff0c;毕竟跨境电商平台内卷严重&#xff0c;平台规则限制不断升级&#xff0c;脱离平台“绑架”布局独立站&#xff0c;才能获得更多流量、订单、塑造品牌价值。然而&#xff0c;在选择建立外贸独立站的过程中&#xff0c;选择适合的建站…...

echarts的bug,在series里写tooltip,不起作用,要在全局先写tooltip:{}才起作用,如果在series里写的不起作用就写到全局里

echarts的bug&#xff0c;在series里写tooltip&#xff0c;不起作用&#xff0c;要在全局先写tooltip&#xff1a;{show:true}才起作用&#xff0c;如果在series里写的不起作用就写到全局里 series里写tooltip不起作用&#xff0c;鼠标悬浮在echarts图表上时不显示提示 你需要…...

jmeter分布式压测

一、什么是压力测试&#xff1f; 压力测试&#xff08;Stress Test&#xff09;&#xff0c;也称为强度测试、负载测试&#xff0c;属于性能测试的范畴。 压力测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷&#xff0c;长时间或超大负荷地运行被测软件系统&#xff…...

consulmanage部署

一、部署consul 使用yum方式部署consul yum install -y yum-utils yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo yum -y install consul 执行以下命令获取uuid密钥并记录下来 uuidgen 编辑consul配置文件 vi /etc/consul.d/consul.h…...

大数据软件项目的验收流程

大数据软件项目的验收流程是确保项目交付符合预期需求和质量标准的关键步骤。以下是一般的大数据软件项目验收流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.项目验收计划制定&#xff1a; 在…...

《第一行代码Andorid》阅读笔记-第一章

这篇文章是我自己的《第一行代码Andorid》的阅读笔记&#xff0c;虽然大量参考了别人已经写好的一些笔记和代码但是也有自己的提炼和新的问题在里面&#xff0c;我也会放上参考文章链接。 学习重点 Android系统的四大组件&#xff1a; &#xff08;1&#xff09;活动&#xff…...

Educational Codeforces Round 146 (Rated for Div. 2)(VP)

写个题解 A. Coins void solve(){ll n, k; cin >> n >> k;bl ok true;if (n &1 && k %2 0) ok false;print(ok ? yes : no); } B. Long Legs void solve(){db x, y; cin >> x >> y;if (x < y) swap(x, y);int t1 ceil(sqrt(x))…...

9.30国庆

消息队列完成进程间通信 #include <myhead.h>#define size sizeof(msg_ds)-sizeof(long) //正文大小//消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }msg_ds;//创建子线程构造体 void *task1(void *arg) {//创造第二个key值ke…...

java基础-第4章-面向对象(二)

一、static关键字 静态&#xff08;static&#xff09;可以修饰属性和方法。 称为静态属性&#xff08;类属性&#xff09;、静态方法&#xff08;类方法&#xff09;。 静态成员是全类所有对象共享的成员。 在全类中只有一份&#xff0c;不因创建多个对象而产生多份。 不必创…...

flex加 grid 布局笔记

<style> .flex-container { display: flex; height: 100%; /* 设置容器的高度 */ } .wide { display: flex; padding: 10px; border: 1px solid lightgray; text-align: center; justify-content: …...

最高评级!华为云CodeArts Board获信通院软件研发效能度量平台先进级认证

9月26日&#xff0c;华为云CodeArts Board获得了中国信通院《云上软件研发效能度量分级模型》的先进级最高级评估&#xff0c;达到了软件研发效能度量平台评估的通用效能度量能力、组织效能模型、项目效能模型、资源效能模型、个人效能模型、研发效能评价模型、项目管理域、开发…...

图像上传功能实现

一、后端 文件存放在images.path路径下 package com.like.common;import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annot…...

03_Node.js模块化开发

1 Node.js的基本使用 1.1 NPM nodejs安装完成后&#xff0c;会跟随着自动安装另外一个工具npm。 NPM的全称是Node Package Manager&#xff0c;是一个NodeJS包管理和分发工具&#xff0c;已经成为了非官方的发布Node模块&#xff08;包&#xff09;的标准。 2020年3月17日&…...

Nginx支持SNI证书,已经ssl_server_name的使用

整理了一些网上的资料&#xff0c;这里记录一下&#xff0c;供大家参考 什么是SNI&#xff1f; 传统的应用场景中&#xff0c;一台服务器对应一个IP地址&#xff0c;一个域名&#xff0c;使用一张包含了域名信息的证书。随着云计算技术的普及&#xff0c;在云中的虚拟机有了一…...

Hive【Hive(六)窗口函数】

窗口函数&#xff08;window functions&#xff09; 概述 定义 窗口函数能够为每行数据划分 一个窗口&#xff0c;然后对窗口范围内的数据进行计算&#xff0c;最后将计算结果返回给该行数据。 语法 窗口函数的语法主要包括 窗口 和 函数 两个部分。其中窗口用于定义计算范围…...

Met no ‘TRANSLATIONS’ entry in project

这里写自定义目录标题 问题描述&#xff1a;解决方法&#xff1a; 问题描述&#xff1a; 多工程项目&#xff0c;执行完update Translation生成了.ts文件&#xff0c;也用翻译工具翻译完了&#xff0c;执行release时&#xff0c;报错“Met no ‘TRANSLATIONS’ entry in proje…...

wordpress 一栏/系列推广软文范例

题 目 非线性规划的MATLAB解法及其应用(一) 问题描述非线性规划是具有非线性约束条件或目标函数的数学规划&#xff0c;是运筹学的一个重要分支。非线性规划是20世纪50年代才开始形成的一门新兴学科。70年代又得到进一步的发展。非线性规划在工程、管理、经济、科研、军事等方面…...

我找伟宏篷布我做的事ko家的网站/怎么注册自己的网站

Mysql3306端口被占用&#xff0c;妙招轻松解决早晨发现mysql服务器意外停止服务&#xff0c;造成网站无法打开&#xff0c;查看mysql日志(注&#xff1a;该日志在msyql安装目录下data文件夹里&#xff0c;文件名是机器名.err,该文件可用记事本打开)发现如下问题;120525 3:35:48…...

怎样做网站标题的图标/深圳网站优化平台

现在我们可以安全地使用 SVG 图像&#xff0c;除非您有很多用户使用 IE8 以及更低版本&#xff0c;或者使用较旧的 Android 设备。这种情况下&#xff0c;依然存在着备选方案。 SVG 是一种 vector 图像文件格式。这使得它们与其他图像格式&#xff08;如 PNG、GIF 或 JPG&am…...

网站诊断工具/网站推广软件免费版大全

wx.getUserInfo不支持的解决方案参考文章&#xff1a; &#xff08;1&#xff09;wx.getUserInfo不支持的解决方案 &#xff08;2&#xff09;https://www.cnblogs.com/daidao/p/9177405.html 备忘一下。...

手机创建微信公众号/seo怎么做关键词排名

2019独角兽企业重金招聘Python工程师标准>>> 1. 学习每一门新技术都是从HelloWorld小案例开始&#xff0c;这仿佛是IT界无形的铁律了&#xff0c;今天也不例外,以下是flume配置文件中配置信息。 agent.sources s1 agent.channels c1 agent.sinks k1 agent.s…...

做b612表情的素材网站/东莞网络推广策略

CentOS7 kernel-3.10.0-693.el7.centos.toa.x86_64.rpm 网盘链接&#xff1a;https://pan.baidu.com/s/1cXB_3qPOnTiIGijFlQ_uzw将文件上传到服务器。 直接rpm安装会报错&#xff0c;如下&#xff1a; [rootlocalhost CentOS 7.2 64]# rpm -ivh kernel-3.10.0-693.el7.centos.t…...