gRPC-Methoden, die beim Umgang mit Protokollpuffern verwendet werden, geben Python CopyFrom, Extend ein

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.

Zuweisungsverarbeitung für Protokollpuffertypen mit der CopyFrom-Methode

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.

Wiederholte Typzuweisung mit Erweitern

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

gRPC-Methoden, die beim Umgang mit Protokollpuffern verwendet werden, geben Python CopyFrom, Extend ein
Vorsichtsmaßnahmen beim Umgang mit ROS MultiArray in Python
Vorsichtsmaßnahmen beim Umgang mit Kontrollstrukturen in Python 2.6
Zeichenkodierung beim Umgang mit Dateien in Python 3
Japanische Ausgabe beim Umgang mit Python im Visual Studio
Lesen Sie die Protokollpufferdaten mit Python3
Bis zum Umgang mit Python in Atom
Tipps zum Umgang mit Binärdateien in Python
Fügen Sie Protokollpuffer mit Python in SQLite ein
Umgang mit "Jahren und Monaten" in Python
[Python] Umgang mit mehreren Aufruffehlern in ray.init
Um Japanisch mit Python in der Docker-Umgebung verwenden zu können
Mailbox-Auswahl beim Abrufen von Google Mail mit imaplib von Python
Organisieren Sie Typen in Python
Problem, Parameter beim Umgang mit Blender aus Python nicht zu kennen
Vorsichtsmaßnahmen bei der Verwendung von Python mit AtCoder
Skripte, die bei der Verwendung von Bottle in Python verwendet werden können
Dinge, die Sie bei der Verwendung von CGI mit Python beachten sollten.
Hier finden Sie eine Zusammenfassung der Dinge, die beim Umgang mit komplexen Zahlen in Python hilfreich sein können
Erweitern Sie Python in C ++ (Boost.NumPy)
Schaben mit Selen in Python
Verwenden Sie das Messprotokoll mit Python
Betreiben Sie LibreOffice mit Python
Schaben mit Chromedriver in Python
Debuggen mit pdb in Python
Umgang mit Sounds in Python
Scraping mit Selen in Python
Scraping mit Tor in Python
Tweet mit Bild in Python
Achtung bei os.mkdir in Python
Kombiniert mit Ordnungszahl in Python
Fehler beim Spielen mit Python
Neue Funktionen in Python 3.9 (1) - Der Summensatzoperator kann im Wörterbuchtyp verwendet werden.