python和go相互调用的两种方法
在Python和Go之间互相调用一个函数有两种常见的方法:使用Cython或者使用gRPC。
使用Cython:
Cython是一个可以将Python代码编译为C的编译器,可以用来调用Go编写的函数。
Go代码(example.go
):
package main
import "C"
//export Sum
func Sum(a, b int) int {
return a + b
}
func main() {}
Python代码(example.pyx
):
# distutils: language = c++
# distutils: sources = example.go
from cpython.ref cimport PyCapsule
cdef extern from "Python.h":
object PyCapsule_New(void *pointer, char *name, PyCapsuleDestructor destructor)
cdef extern from "example.h":
int Sum(int a, int b)
def py_sum(a, b):
return Sum(a, b)
使用gRPC:
gRPC是一个高性能、开源和通用的RPC(远程过程调用)框架,它可以在多种语言之间工作。
Go代码(greeter_server.go
):
package main
import (
"net"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
const (
port = ":50051"
)
// server structure
type server struct{}
// GreeterClient is the client API for Greeter service.
// We can define multiple gRPC service in the same .proto file.
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
func (s *server) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
return &HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
panic(err)
}
s := grpc.NewServer()
reflection.Register(s)
RegisterGreeterServer(s, &server{})
if err := s.Serve(lis); err != nil {
panic(err)
}
}
Python代码(greeter_client.py
):
import grpc
from greeter_pb2 import HelloRequest
from greeter_pb2_grpc import GreeterStub
with grpc.insecure_channel('localhost:50051') as channel:
stub = GreeterStub(channel)
response = stub.SayHello(HelloRequest(Name='World'))
print("Greeter client received: " + response.Message)
在这两种方法中,使用Cython的方法更为直接,但是它需要你写Cython代码并且处理C类型的数据。使用gRPC的方法更为复杂,但是它提供了一个更为通用和灵活的方式来在不同语言之间进行通信。
评论已关闭