Python:使用json序列化的奇怪的枚举子类行为

时间:2017-07-05 08:39:03

标签: python json serialization enums nameko

我尝试将一些数据作为参数发送到使用Nameko和rabbitmq到微服务的远程过程时遇到奇怪的行为:

在名为project的目录下构建3个文件的问题的简化:

serializer.py ,自定义json编码/解码对象

from enum import Enum
import json
from project.service import CustomEnum

class CustomEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, CustomEnum):
            #  return {'__enum__': str(o)}
            return {'__enum__': o.name}
        return {'__{}__'.format(o.__class__.__name__): o.__dict__}

class CustomDecoder(json.JSONDecoder):
    def __init__(self, *args, **kwargs):
        json.JSONDecoder.__init__(self, 
                                  object_hook=self.object_hook, 
                                  *args, **kwargs)

    def object_hook(self, o):
        if '__enum__' in o:
            return CustomEnum[o['__enum__']]
            # name, member = o['__enum__'].split('.')
            # return getattr(ENUMS[name], member)
        return o

service.py ,基本的微服务

from enum import Enum
from nameko.rpc import rpc
import json

from project.serializer import CustomDecoder


class CustomEnum(Enum):
    A = 0
    B = 1

class Service(object):
    name = "service"

    @rpc
    def get_enum(self, enum_type):
        enum_type = json.loads(enum_type, cls=CustomDecoder)
        if enum_type == CustomEnum.A:
            return "A"
        elif enum_type == CustomEnum.B:
            return "B"
        return "NO ENUM"

Nameko shell 在按照以下步骤启动RabbitMQ docker实例和nameko运行服务后试用:

  • $ docker run -d --hostname rabbit --name my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
  • $ nameko run project.service --broker amqp://guest:guest@localhost
  • $ nameko shell --broker amqp://guest:guest@localhost

测试后的shell输出:

In [1]: import json
In [2]: from project.serializer import CustomEncoder
In [3]: from project.service import CustomEncoder
In [4]: serialized = json.dumps(CustomEnum.A, cls=CustomEncoder)
In [5]: n.rpc.service.get_enum(serialized)
NO ENUM

似乎在远程过程type(enum_type) == type(CustomEnum)上反序列化后给出 False ,在nameko shell中尝试它时,它完全序列化并反序列化枚举子类类型。 它可能与nameko本身序列化已经序列化的数据有关吗?我知道我应该将自定义序列化程序注册到kombu.serialization.register,但我仍然坚持这一点,我想知道为什么会这样。

0 个答案:

没有答案