Python,Go开发民营企业从粗放期到国际化标准化App(附代码)
Python + Go 开发国际化标准化全流程 App”这个主题,提供一些具体的代码示例来支撑之前的架构方案。
下面我会给出几个关键的技术片段,涵盖:
1. gRPC 服务定义与通信(Go 服务端 + Python 客户端)
2. 国际化(i18n)文本处理(Python + Go 示例)
3. 标准化配置管理(环境变量 + 配置文件)
4. 统一日志格式(JSON 结构化日志)
这些代码可以直接用到你的项目中,帮助实现“草根 → 国际化标准化”的落地。
---
1. gRPC 跨语言通信(Go 服务端,Python 客户端)
1.1 定义 user.proto
```protobuf
syntax = "proto3";
package user;
option go_package = "./user";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
string user_id = 1;
}
message UserResponse {
string user_id = 1;
string name = 2;
string email = 3;
string lang = 4; // 用户语言偏好,用于国际化
}
```
生成代码(Go 使用 protoc-gen-go,Python 使用 grpcio-tools)。
1.2 Go 服务端实现
```go
package main
import (
"context"
"net"
"log"
"google.golang.org/grpc"
pb "your-project/user"
)
type server struct {
pb.UnimplementedUserServiceServer
}
func (s *server) GetUser(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {
// 模拟从数据库查询
return &pb.UserResponse{
UserId: req.UserId,
Name: "张三",
Email: "zhang.san@example.com",
Lang: "zh-CN",
}, nil
}
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer()
pb.RegisterUserServiceServer(s, &server{})
log.Fatal(s.Serve(lis))
}
```
1.3 Python 客户端调用
```python
import grpc
import user_pb2
import user_pb2_grpc
def get_user(user_id: str):
channel = grpc.insecure_channel('localhost:50051')
stub = user_pb2_grpc.UserServiceStub(channel)
request = user_pb2.UserRequest(user_id=user_id)
response = stub.GetUser(request)
print(f"User: {response.name}, Lang: {response.lang}")
if __name__ == '__main__':
get_user("123")
```
---
2. 国际化(i18n)文本处理
2.1 Python 使用 gettext + JSON 文件
```python
import gettext
import json
# 加载语言文件
zh_trans = gettext.translation('messages', localedir='locales', languages=['zh_CN'])
zh_trans.install()
_ = zh_trans.gettext
# 或者直接用 JSON 做简单切换
messages = {
'en': {'welcome': 'Welcome'},
'zh': {'welcome': '欢迎'}
}
def i18n(key, lang='en'):
return messages.get(lang, messages['en']).get(key, key)
print(i18n('welcome', 'zh')) # 输出:欢迎
```
2.2 Go 使用 go-i18n 库
```go
package main
import (
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
bundle.LoadMessageFile("active.en.json")
bundle.LoadMessageFile("active.zh.json")
localizer := i18n.NewLocalizer(bundle, "zh-CN")
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "welcome",
})
println(msg) // 输出:欢迎
}
```
active.zh.json 示例:
```json
{
"welcome": "欢迎",
"userNotFound": "用户不存在"
}
```
---
3. 标准化配置管理(12-Factor App 风格)
3.1 Go 使用 viper
```go
import "github.com/spf13/viper"
func init() {
viper.SetConfigName("config") // config.yaml
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AutomaticEnv() // 环境变量覆盖
viper.ReadInConfig()
}
// 使用
dbHost := viper.GetString("database.host")
```
3.2 Python 使用 pydantic + .env
```python
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "MyApp"
database_url: str
redis_host: str = "localhost"
class Config:
env_file = ".env"
settings = Settings()
print(settings.database_url)
```
---
4. 统一结构化日志(JSON 格式,便于采集)
4.1 Go 使用 logrus
```go
import log "github.com/sirupsen/logrus"
func main() {
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(log.Fields{
"user_id": "123",
"action": "login",
}).Info("user logged in")
}
```
输出:
```json
{"action":"login","level":"info","msg":"user logged in","time":"...","user_id":"123"}
```
4.2 Python 使用 python-json-logger
```python
from pythonjsonlogger import jsonlogger
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("user login", extra={"user_id": "123", "action": "login"})
```
输出:
```json
{"asctime": "...", "levelname": "INFO", "message": "user login", "user_id": "123", "action": "login"}
```
---
5. 一个完整的微服务调用示例(Python → Go → 国际化响应)
场景:Python Web 层接收请求(带 Accept-Language 头),调用 Go gRPC 服务,返回国际化后的用户信息。
```python
# Python 客户端(带语言偏好)
def get_user_grpc(user_id: str, lang: str):
channel = grpc.insecure_channel('user-service:50051')
stub = user_pb2_grpc.UserServiceStub(channel)
metadata = (('accept-language', lang),)
response = stub.GetUser(user_pb2.UserRequest(user_id=user_id), metadata=metadata)
# response 中包含 lang 字段,可根据该字段再次本地化
return response
```
在 Go 服务端中读取 metadata:
```go
func (s *server) GetUser(ctx context.Context, req *pb.UserRequest) (*pb.UserResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
lang := "en"
if vals := md.Get("accept-language"); len(vals) > 0 {
lang = vals[0]
}
// 根据 lang 返回本地化文本...
}
```
---
总结
以上代码示例覆盖了从跨语言通信、国际化文本、标准化配置到可观测日志的核心环节。你可以把这些片段集成到你现有的 Python/Go 项目中,逐步实现从“草莽”到“国际标准化”的演进。
如果你的团队现在还没有使用 gRPC 或结构化日志,我建议先从 gRPC + Python 客户端/Go 服务端 入手,这是两种语言协作最标准的方式。
