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通用性强,消息队列适合异步处理,共享文件简单但效率较低。

相关推荐
他们都不看好你,偏偏你最不争气2 小时前
【iOS】AFNetworking
开发语言·macos·ios·objective-c
zhanggui4 小时前
iOS Debug Symbols
ios·xcode·debug symbox
库奇噜啦呼9 小时前
【iOS】static、const、extern关键字
ios
zzywxc78710 小时前
AI工具全景洞察:从智能编码到模型训练的全链路剖析
人工智能·spring·ios·prompt·ai编程
前端 贾公子11 小时前
《Vuejs设计与实现》第 16 章(解析器) 上
vue.js·flutter·ios
Digitally20 小时前
如何将大型音频文件从 iPhone 发送到不同的设备
ios·iphone
SunkingYang20 小时前
iPhone 17系列包含哪些版本,各版本又有哪些配置,硬件、功能、性能、价格详细介绍
iphone·配置·硬件·性能·区别·价格·iphone17
吴Wu涛涛涛涛涛Tao1 天前
Flutter 实现「可拖拽评论面板 + 回复输入框 + @高亮」的完整方案
android·flutter·ios