简体   繁体   English

Python序列化问题

[英]Python serialization issue

I am getting a json message/event with messed up types like: 我收到的JSON消息/事件的类型混乱:

{
    "AdminCreateUserConfig": {
      "UnusedAccountValidityDays": "7",
      "AllowAdminCreateUserOnly": "true"
    }
    ...
}

I figured out that the best way is to serialize and deserialize using a custom serializer 我发现最好的方法是使用自定义序列化程序进行序列化和反序列化

code: 码:

event = json.loads( json.dumps(event, mySerializer) )

def mySerializer(o):
    if isinstance(o, unicode): 
        if o in ["true", "True"]: return True
        elif o in ["false", "False"]: return False
        else: 
            try:
                return int(o)
            except:
                return o
    else:
        return o.__dict__

But my problem is that after the serialization and deserialization I still get the same strings/unicodes: 但是我的问题是,在序列化和反序列化之后,我仍然得到相同的字符串/ unicode:

AdminCreateUserConfig.UnusedAccountValidityDays: 7, type: <type 'unicode'>
AdminCreateUserConfig.AllowAdminCreateUserOnly: true, type: <type 'unicode'>

What should I change? 我应该改变什么?

TLDR: I am in AWS Lambda, and I have the json Object, this is why I need to do the conversion two more times. TLDR:我在AWS Lambda中,并且拥有json对象,这就是为什么我需要再进行两次转换的原因。

In order to access the key-value pairs of objects as they are being decoded, you need to define an object_pairs_hook method: 为了在对象的键值对被解码时访问它们,您需要定义一个object_pairs_hook方法:

def object_pairs_hook(pairs):
    decoded_pairs = []
    for key, val in pairs:
        # python 2/3 compatability support
        try:
            type_ = unicode
        except NameError:
            type_ = str

        if isinstance(val, type_):
            if val.lower() == "true":
                val = True
            elif val.lower() == "false":
                val = False
            else:
                try:
                    val = int(val)
                except ValueError:
                    pass

        decoded_pairs.append((key, val))

    return dict(decoded_pairs)

Which you can then use like this: 然后,您可以像这样使用它:

>>> import json
>>> json.loads('{ "hi": { "foo": "true", "bar": "2" } }', object_pairs_hook=object_pairs_hook)
{u'hi': {u'foo': True, u'bar': 2}}

The object_hook method (or providing a custom JSONDecoder class) will only be called for objects and will not be called for keys and values of objects. object_hook方法(或提供自定义JSONDecoder类)将仅针对对象被调用,而不会针对对象的键和值被调用。

Using Marshmallow 使用棉花糖

If your data is well-formed, it would be better to use a library like marshmallow which already handles cases like this. 如果您的数据格式正确,则最好使用像棉花糖这样的库,该库已经可以处理此类情况。 To use it you would define a schema: 要使用它,您将定义一个模式:

import marshmallow

class AdminCreateUserConfig(marshmallow.Schema):
    UnusedAccountValidityDays = marshmallow.fields.Int()
    AllowAdminCreateUserOnly = marshmallow.fields.Bool()

class MySchema(marshmallow.Schema):
    AdminCreateUserConfig = marshmallow.fields.Nested(AdminCreateUserConfig)

And then you can call loads to deserialize: 然后,您可以调用负载进行反序列化:

>>> MySchema().loads('{ "AdminCreateUserConfig": { "UnusedAccountValidityDays": "7", "AllowAdminCreateUserOnly": "true" } }')
{'AdminCreateUserConfig': {'UnusedAccountValidityDays': 7, 'AllowAdminCreateUserOnly': True}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM