web-dev-qa-db-fra.com

Obtenir tous les noms de champs à partir d'un tampon de protocole?

Je veux obtenir tous les noms de champs d'un proto dans une liste. Y a-t-il un moyen de faire cela? J'ai regardé dans la documentation et il ne semble rien y avoir pour ça.

28
user2253332

Chaque classe proto possède une variable de classe DESCRIPTOR qui peut être utilisée pour inspecter les champs des messages protobuf correspondants.

Jetez un œil à la documentation des classes Descriptor et FieldDescriptor pour plus de détails.

Voici un exemple simple pour obtenir les FieldDescriptors de tous les champs de message dans une liste:

res = message.DESCRIPTOR.fields

Pour obtenir les noms des champs "exactement tels qu'ils apparaissent dans le fichier .proto":

res = [field.name for field in message.DESCRIPTOR.fields]

ou (à partir des commentaires):

res = message.DESCRIPTOR.fields_by_name.keys()

Pour obtenir les noms complets des champs "y compris l'étendue contenant":

res = [field.full_name for field in message.DESCRIPTOR.fields]
28
qfiard

qfiard's réponse n'a pas fonctionné pour moi. L'appel de message.DESCRIPTOR.fields.keys() a produit AttributeError: 'list' object has no attribute 'keys'.

Je ne sais pas pourquoi cela ne fonctionnerait pas. Peut-être que cela a quelque chose à voir avec la façon dont le message a été défini/compilé.

La solution de contournement consistait à composer une liste des objets de champ individuels et à obtenir la propriété name pour chacun. Cela m'a donné une liste de chaînes de tous les champs de cette liste.

res = [f.name for f in message.DESCRIPTOR.fields]

Notez que cela ne vous permet pas d'obtenir les noms de champ dans ces champs de manière récursive.

13
ypx