Python与Go结合

Python与Go结合的方法

Python和Go可以通过多种方式结合使用,通常采用跨语言通信或集成的方式。以下是几种常见的方法:

使用CFFI或CGO进行绑定

Python可以通过CFFI(C Foreign Function Interface)调用Go编写的库,而Go可以通过CGO导出函数供Python调用。这种方法需要将Go代码编译为动态链接库(.so或.dll文件),然后在Python中加载并调用。

在Go中编写并导出函数:

go 复制代码
package main

import "C"

//export Add
func Add(a, b int) int {
    return a + b
}

func main() {}

编译为动态库:

bash 复制代码
go build -buildmode=c-shared -o libadd.so add.go

在Python中使用CFFI调用:

python 复制代码
from cffi import FFI

ffi = FFI()
ffi.cdef("int Add(int a, int b);")
lib = ffi.dlopen("./libadd.so")

result = lib.Add(2, 3)
print(result)  # 输出5

使用gRPC进行通信

gRPC是一个高性能的远程过程调用框架,支持多种语言。可以在Go中实现gRPC服务端,在Python中实现客户端,或反之。

定义proto文件:

proto 复制代码
syntax = "proto3";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 2;
}

Go实现服务端:

go 复制代码
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "path/to/your/proto"
)

type server struct{}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    s.Serve(lis)
}

Python实现客户端:

python 复制代码
import grpc
from proto import greeter_pb2, greeter_pb2_grpc

channel = grpc.insecure_channel('localhost:50051')
stub = greeter_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(greeter_pb2.HelloRequest(name='World'))
print(response.message)  # 输出 "Hello World"

使用HTTP/REST API

Go可以提供一个HTTP服务,Python通过HTTP请求与之交互。这是最通用的方法之一。

Go实现HTTP服务:

go 复制代码
package main

import (
    "encoding/json"
    "net/http"
)

type Response struct {
    Message string `json:"message"`
}

func handler(w http.ResponseWriter, r *http.Request) {
    resp := Response{Message: "Hello from Go"}
    json.NewEncoder(w).Encode(resp)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Python使用requests调用:

python 复制代码
import requests

response = requests.get("http://localhost:8080")
print(response.json())  # 输出 {"message": "Hello from Go"}

使用消息队列

通过消息队列(如RabbitMQ、Kafka)可以实现Python和Go之间的异步通信。Python作为生产者发送消息,Go作为消费者处理消息,或反之。

Python使用pika发送消息:

python 复制代码
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='', routing_key='hello', body='Hello from Python')
connection.close()

Go使用amqp接收消息:

go 复制代码
package main

import (
    "log"
    
    "github.com/streadway/amqp"
)

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    ch, err := conn.Channel()
    if err != nil {
        log.Fatal(err)
    }
    defer ch.Close()

    q, err := ch.QueueDeclare("hello", false, false, false, false, nil)
    if err != nil {
        log.Fatal(err)
    }

    msgs, err := ch.Consume(q.Name, "", true, false, false, false, nil)
    if err != nil {
        log.Fatal(err)
    }

    for d := range msgs {
        log.Printf("Received a message: %s", d.Body)
    }
}

使用共享内存或文件

对于简单的数据交换,可以通过共享文件或内存实现。Python和Go都可以读写相同的文件或共享内存区域。

Python写入文件:

python 复制代码
with open("shared.txt", "w") as f:
    f.write("Hello from Python")

Go读取文件:

go 复制代码
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    data, err := ioutil.ReadFile("shared.txt")
    if err != nil {
        fmt.Println("Error reading file:", err)
        return
    }
    fmt.Println(string(data))  // 输出 "Hello from Python"
}

这些方法各有优缺点,适用于不同的场景。CFFI/CGO适合高性能调用,gRPC适合复杂服务,HTTP/REST通用性强,消息队列适合异步处理,共享文件简单但效率较低。

相关推荐
CocoaKier21 小时前
苹果谷歌商店:如何监控并维护用户评分评论
ios·google·apple
iOS日常1 天前
iOS设备崩溃日志获取与查看
ios·xcode
wangruofeng1 天前
AI 助力 Flutter 3.27 升级到 3.38 完整指南:两周踩坑与实战复盘
flutter·ios·ai编程
iOS日常2 天前
Xcode 垃圾清理
ios·xcode
开心就好20252 天前
不越狱能抓到 HTTPS 吗?在未越狱 iPhone 上抓取 HTTPS
后端·ios
傅里叶2 天前
iOS相机权限获取
flutter·ios
zhangkai3 天前
flutter存储知识点总结
flutter·ios
齐生13 天前
网络知识点 - TCP/IP 四层模型知识大扫盲
笔记·ios
IT技术分享社区3 天前
数码资讯:iPhone 18 Pro,十大升级细节浮出水面
ios·手机·iphone
嵌入式学习菌3 天前
https不校验证书实现及https接口实现
ios·iphone