【问题标题】:Parsing Google Fonts METADATA.pb - google.protobuf.message.DecodeError: Error parsing message解析 Google 字体 METADATA.pb - google.protobuf.message.DecodeError:解析消息时出错
【发布时间】:2019-12-11 06:04:19
【问题描述】:

我正在尝试解析来自官方 Google 字体存储库的 METADATA.pb 文件,该文件可在此处找到:https://github.com/google/fonts(Roboto 字体的示例 METADATA.pb 文件:https://github.com/google/fonts/blob/master/apache/roboto/METADATA.pb

要解析 proto-buf 文件,需要正确的格式。它可以在这里下载为“public_fonts.proto”:https://github.com/googlefonts/gftools/blob/master/Lib/gftools/fonts_public.proto

我使用它通过以下命令生成了一个名为“fonts_public_pb2.py”的 Python 代码文件:

protoc -I=. --python_out=. fonts_public.proto

这是我的代码,它导入这个生成的文件,读取 METADATA.pb 文件的内容(不管是哪一个,它们都遵循相同的结构),然后尝试解析 proto-buf 字符串。

#! /usr/bin/env python

import fonts_public_pb2

protobuf_file_path = 'METADATA.pb'
protobuf_file = open(protobuf_file_path, 'rb')
protobuf = protobuf_file.read()

font_family = fonts_public_pb2.FamilyProto()
font_family.ParseFromString(protobuf)

只有几行,没什么复杂的,但输出总是一样的:

Traceback (most recent call last):
  File "parse.py", line 22, in <module>
    font_family.ParseFromString(protobuf)
google.protobuf.message.DecodeError: Error parsing message

我通常不使用 Python 编码,所以这里的问题很可能是我,但在尝试了一些不同的事情之后,我不知道该怎么做了:

  • 使用了来自 gftools 存储库的已经生成的“fonts_public_pb2.py”文件:https://github.com/googlefonts/gftools/blob/master/Lib/gftools/fonts_public_pb2.py - 我从“public_fonts.proto”文件生成的输出和这个文件几乎相同,我检查了 Meld。错误还是一样
  • 将 .proto 文件中的所有“必填”字段设置为“可选”,再次生成“fonts_public_pb2.py”文件 - 相同的错误
  • 尝试了 Python 2 和 3 - 相同的错误

【问题讨论】:

    标签: python python-3.x fonts protocol-buffers google-fonts


    【解决方案1】:

    那些 METADATA.pb 文件不是二进制 protobuf 文件,它们使用 text format

    import fonts_public_pb2
    from google.protobuf import text_format
    
    protobuf_file_path = 'METADATA.pb'
    protobuf_file = open(protobuf_file_path, 'r')
    protobuf = protobuf_file.read()
    
    font_family = fonts_public_pb2.FamilyProto()
    text_format.Merge(protobuf, font_family)
    print(font_family)
    

    【讨论】:

    • 好的,第一:非常非常感谢,或者,因为我们都是德国人:Danke dir :) 第二:我自己也想不通,我只是假设@987654323 @ 需要...一个字符串!?!第三:您能否在答案中从“rb”中删除“b”?在这里,一个“真实”的字符串是必要的,否则它会显示这个错误:TypeError: a bytes-like object is required, not 'str'Thanks :)
    • 不客气,gern geschehen。 ParseFromString 确实想要一个字符串......字节!当然不是方法名历史上最明显的方法名。我已经更正了代码,尽管它在我的机器上似乎没有任何区别(macOS 上的 Python 3)。
    猜你喜欢
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多