ParseFromString возвращает размер файла двоичного файла, а не данных

#python #protocol-buffers

Вопрос:

Я пытаюсь получить данные из двоичного файла (в частности, новый формат файла последовательности OnlineSequencer) с помощью буфера протокола Google, но все, что он печатает, — это размер файла. Я скомпилировал оба файла .proto, используемые им для сценариев python: sequence.proto:

     syntax = "proto3";

import "note_type.proto";

message Note {
  NoteType type = 1;
  float time = 2;
  float length = 3;
  int32 instrument = 4;
  float volume = 5;
}

message Marker {
  float time = 1;
  int32 setting = 2;
  int32 instrument = 3;
  float value = 4;
  bool blend = 5;
}

message InstrumentSettings {
  float volume = 1;
  bool delay = 2;
  bool reverb = 3;
  float pan = 4;
  bool enable_eq = 5;
  float eq_low = 6;
  float eq_mid = 7;
  float eq_high = 8;
  float detune = 9;
}

message SequenceSettings {
  int32 bpm = 1;
  int32 time_signature = 2;
  map<int32, InstrumentSettings> instruments = 3;
  // Storing volume as (1 - volume) so it defaults to volume=1.
  float one_minus_volume = 4;
}

message Sequence {
  SequenceSettings settings = 1;
  repeated Note notes = 2;
  repeated Marker markers = 3;
}
 

примечание_тип.прото:

 syntax = "proto3";

enum NoteType {
  C0 = 0;
  CS0 = 1;
  D0 = 2;
  DS0 = 3;
  E0 = 4;
  F0 = 5;
  FS0 = 6;
  G0 = 7;
  GS0 = 8;
  A0 = 9;
  AS0 = 10;
  B0 = 11;
  C1 = 12;
  CS1 = 13;
  D1 = 14;
  DS1 = 15;
  E1 = 16;
  F1 = 17;
  FS1 = 18;
  G1 = 19;
  GS1 = 20;
  A1 = 21;
  AS1 = 22;
  B1 = 23;
  C2 = 24;
  CS2 = 25;
  D2 = 26;
  DS2 = 27;
  E2 = 28;
  F2 = 29;
  FS2 = 30;
  G2 = 31;
  GS2 = 32;
  A2 = 33;
  AS2 = 34;
  B2 = 35;
  C3 = 36;
  CS3 = 37;
  D3 = 38;
  DS3 = 39;
  E3 = 40;
  F3 = 41;
  FS3 = 42;
  G3 = 43;
  GS3 = 44;
  A3 = 45;
  AS3 = 46;
  B3 = 47;
  C4 = 48;
  CS4 = 49;
  D4 = 50;
  DS4 = 51;
  E4 = 52;
  F4 = 53;
  FS4 = 54;
  G4 = 55;
  GS4 = 56;
  A4 = 57;
  AS4 = 58;
  B4 = 59;
  C5 = 60;
  CS5 = 61;
  D5 = 62;
  DS5 = 63;
  E5 = 64;
  F5 = 65;
  FS5 = 66;
  G5 = 67;
  GS5 = 68;
  A5 = 69;
  AS5 = 70;
  B5 = 71;
  C6 = 72;
  CS6 = 73;
  D6 = 74;
  DS6 = 75;
  E6 = 76;
  F6 = 77;
  FS6 = 78;
  G6 = 79;
  GS6 = 80;
  A6 = 81;
  AS6 = 82;
  B6 = 83;
  C7 = 84;
  CS7 = 85;
  D7 = 86;
  DS7 = 87;
  E7 = 88;
  F7 = 89;
  FS7 = 90;
  G7 = 91;
  GS7 = 92;
  A7 = 93;
  AS7 = 94;
  B7 = 95;
  C8 = 96;
  CS8 = 97;
  D8 = 98;
  DS8 = 99;
  E8 = 100;
  F8 = 101;
  FS8 = 102;
  G8 = 103;
  GS8 = 104;
  A8 = 105;
  AS8 = 106;
  B8 = 107;
}
 

Основной сценарий:

 import sequence_pb2
f = open('./test.sequence', 'rb')
print(f)
sequence = sequence_pb2.Sequence()
print(sequence)
print(sequence.ParseFromString(f.read()))
f.close()
 

Я не уверен, почему это не работает. Если у меня есть файл в папке скрипта, он просто выводит размер файла в байтах. В прошлом я никогда особо не работал с двоичными файлами, так что я довольно новичок в такого рода вещах. Если бы я мог получить помощь в этом, это было бы здорово.

Ответ №1:

ParseFromString Метод возвращает количество проанализированных байтов (см. документ doc) и сохраняет содержимое в самом экземпляре.

Возможно, вы захотите просмотреть содержимое sequence объекта после синтаксического анализа:

 sequence = sequence_pb2.Sequence()
sequence.ParseFromString(f.read())
print(sequence)