Wenn Sie gRPC mit Python verwenden, verwenden Sie den Typ protocolbuffer (pb2). Beim Umgang mit diesem Protokollpuffertyp sind einige Punkte zu beachten, daher werde ich ihn im Artikel zusammenfassen.
Zum Beispiel, wenn Sie die folgende Proto-Definition haben: Einfaches Design mit einer Methode.
user.proto
service UserService {
rpc GetUser(GetUserRequest) returns (User) {}
}
message Size {
int32 height = 1;
int32 weight = 2;
}
message User {
string id = 1;
string name = 2;
Size size = 3;
}
message GetUserRequest {
string user_id = 1;
}
Das Folgende ist ein serverseitiges Implementierungsbeispiel für UserService unter Verwendung der obigen Protodatei.
import user_pb2
class UserService():
def GetUser(self, request, context):
#Holen Sie sich den Benutzer von db
db_user = db.get(request.user_id)
#Größe definieren und Mehrwert schaffen
size = user_pb2.Size()
size.height = db_user.height
size.weight = db_user.weight
#Benutzer definieren, Mehrwert schaffen und zurückgeben
user = user_pb2.User()
user.id = db_user.id
user.name = db_user.name
user.size = size
return user
Wenn ich die obige GetUser-Methode ausführe, wird bei TypeError ein Fehler angezeigt. Das Problem ist die vorletzte Codezeile "user.size = size".
Die Größe, bei der es sich um einen Objekttyp vom Typ Größe handelt, entspricht dem im Benutzertyp definierten Größentyp. Wenn Sie ihn jedoch so zuweisen, wie er ist, tritt ein Fehler auf. Die hier verwendete Methode ist CopyFrom. Durch Umschreiben des Problemteils des obigen Codes wie folgt wird der Code ohne TypeError ausgeführt.
import user_pb2
class UserService():
def GetUser(self, request, context):
#Holen Sie sich den Benutzer von db
db_user = db.get(request.user_id)
#Größe definieren und Mehrwert schaffen
size = user_pb2.Size()
size.height = db_user.height
size.weight = db_user.weight
#Benutzer definieren, Mehrwert schaffen und zurückgeben
user = user_pb2.User()
user.id = db_user.id
user.name = db_user.name
user.size.CopyFrom(size)
return user
Selbst wenn Sie mit der Type-Methode vergleichen, ist dies schwer zu bemerken, da das size-Objekt ein Size-Typ ist. Wenn Sie es jedoch als Protokollpuffertyp zuweisen, können Sie es nur dann korrekt zuweisen, wenn Sie CopyFrom verwenden.
Selbst bei wiederholten Definitionen sind beim Zuweisen einige Punkte zu beachten. Dies wird anhand der folgenden Protodatei erläutert, die eine Neufassung des vorherigen UserService darstellt.
User.proto
service UserService {
rpc GetUser(GetUserRequest) returns (User) {}
}
message Item {
string id = 1;
string name = 2;
}
message User {
string id = 1;
string name = 2;
repeated Item items = 3;
}
message GetUserRequest {
string user_id = 1;
}
Ich habe die Größe in einen wiederholten Typ namens Elemente geändert. Unten finden Sie den UserService-Code.
import user_pb2
class UserService():
def GetUser(self, request, context):
#Holen Sie sich den Benutzer von db
db_user = db.get(request.user_id)
#Definieren Sie mehrere Elemente und erstellen Sie eine Elementliste
item1 = user_pb2.Item()
item1.id = '1'
item1.name = 'item1'
item2 = user_pb2.Item()
item2.id = '2'
item2.name = 'item2'
items = [item1, item2]
#Benutzer definieren, Mehrwert schaffen und zurückgeben
user = user_pb2.User()
user.id = db_user.id
user.name = db_user.name
user.items = items
return user
Wenn ich den obigen Code ausführe, erhalte ich immer noch einen TypeError. Der Problemteil ist auch der Teil von "user.items = items". Verwenden Sie die Extend-Methode, um einem wiederholten Feld zuzuweisen.
user.items.extend(items)
Durch die Verwendung von extens wie oben beschrieben ist es möglich, den Wert auf den Typ des Arrays festzulegen.
Ich habe auf der offiziellen Seite von Google usw. nachgesehen, warum es notwendig ist, damit umzugehen, aber es wurde nicht gut erklärt. Der Protokollpuffer scheint eine Gewohnheit in Python zu haben, verwenden Sie ihn also mit Vorsicht!
Recommended Posts