0

我对 Pyro4 完全陌生。我希望提供一个包含属性的 python 类,该属性是编译为 python 类的 protobuf 对象的实例。

import sys
import os
import Pyro4
import MPB_pb2 as mpb  # My Protobuf class

@Pyro4.expose
@Pyro4.behavior(instance_mode="single")
class MyWrappedProtobuf(object):
    def __init__(self):
        self.setup_MyProtobuf()

    def setup_MyProtobuf(self):
        self.__MyProtobuf = mpb.MyProtobufMessage()

    @property
    def MyProtobuf(self):
        return self.__MyProtobuf

设置服务器运行后,我创建服务对象的代理,并查询 MyProtobuf 属性:

u = Pyro4.Proxy('PYRONAME:{}'.format(<server name>)).MyProtobuf

我得到的是一个序列化的对象:

>>>u
{'serialized': '\n$\n\x05world\x12\x1b\t\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00'}

我从文档(https://pythonhosted.org/Pyro4/clientcode.html#sharing-the-way-your-custom-classes-are-de-serialized)中了解到“默认情况下,自定义类被序列化为一个字典. 它们不会反序列化回您的自定义类的实例。”

我正在寻找说明,或者描述如何将这个序列化字典转回我的类的示例,包括该类包含的 protobuf 消息实例。

看起来这一定是一个常见的、微不足道的操作,但我找不到一个很好的例子来展示给我看,并且文档没有提供我可以看到的明确帮助。

谢谢!

4

2 回答 2

1

默认情况下,Pyro 使用 Serpent 序列化器,后者又使用 python 的原始类型将内容序列化为。通常这将是一本字典。如果它是一个不容易识别的类,或者该类没有定义“合适的”序列化方法,它将回退到一个特殊的字典形式,例如:

{
    "__class__":   "pakcage.Classname"
    "property1":   "value1",
    ...
}

你没有在你的序列化表格中看到这个。这意味着不是 Pyro(或 Serpent,而是)为您序列化它。发生的事情(我认为)是 Protobuf 对象定义了一个 __getstate__() 方法,该方法返回您所看到的 protobuf 对象的序列化形式。与此相反的是 __setstate__(...) (这些方法是从 Python 内置的 pickle 序列化器机制中“借用”的)。我没有使用 protobufs 的经验,但我猜这很简单:

u = proxy.MyProtoBuf
message = mpb.MyProtobufMessage()   # create empty protobuf object (??)
message.__setstate__(u)

会成功的。我建议你查看 protobuf 的文档,了解它们的对象是如何序列化的(你可能需要搜索它们是如何被腌制的)。底线;这不是火焰兵(或蛇)可以控制的东西。

于 2019-01-14T20:03:06.207 回答
0

它确实是从我看到的 protobuf 序列化的。一旦那个confucion被排序,我发现序列化的结果是unicode。为了让我能够让 protobuf 反序列化结果,我需要将其编码为纯 ascii(使用<result>.encode('utf-8'))。我不确定为什么它会返回 unicode,此后它不会转身接受。但是,我有一个可行的解决方案。

于 2019-01-15T20:45:19.570 回答