【问题标题】:Nested class in JSON de-serialization using marshmallow使用棉花糖进行 JSON 反序列化的嵌套类
【发布时间】:2019-03-09 20:48:11
【问题描述】:

如何使用棉花糖对嵌套的 JSON 进行反序列化,以便可以使用像 app.data.person.lname 这样的点表示法?目前,我的示例仅向下一层工作,但我无法从嵌套的 person 结构中获取姓氏 (lname):

from marshmallow import Schema, fields, post_load
import datetime as dt
import json

class Person(object):
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

class PersonSchema(Schema):
    fname = fields.Str()
    lname = fields.Str()

class App(object):
    def __init__(self, appid, channel, person):
        self.appid = appid
        self.channel = channel
        self.person = person
        self.created_at = dt.datetime.now()

class AppSchema(Schema):
    appid = fields.Str()
    channel = fields.Str()
    person = fields.Nested(PersonSchema)
    created_at = fields.DateTime()

    @post_load
    def make_user(self, data):
        return App(**data)

json_data = """{
    "appid": "2309wfjwef",
    "channel": "retail",
    "person": {
        "fname": "John",
        "lname": "Doe"
        }
}"""

app_data = json.loads(json_data)

schema = AppSchema()
app = schema.load(app_data)

print(app.data.person.lname)

获取:

AttributeError: 'dict' object has no attribute 'lname'

【问题讨论】:

    标签: python json deserialization marshmallow


    【解决方案1】:

    显然,你需要在PersonSchema中创建Person

    from marshmallow import Schema, fields, post_load
    import datetime as dt
    import json
    
    class Person(object):
        def __init__(self, fname, lname):
            self.fname = fname
            self.lname = lname
    
    class PersonSchema(Schema):
        fname = fields.Str()
        lname = fields.Str()
    
        @post_load
        def make_person(self, data):
            return Person(**data)
    
    
    class App(object):
        def __init__(self, appid, channel, person):
            self.appid = appid
            self.channel = channel
            self.person = person
            self.created_at = dt.datetime.now()
    
    class AppSchema(Schema):
        appid = fields.Str()
        channel = fields.Str()
        person = fields.Nested(PersonSchema)
        created_at = fields.DateTime()
    
        @post_load
        def make_app(self, data):
            return App(**data)
    
    json_data = """{
        "appid": "2309wfjwef",
        "channel": "retail",
        "person": {
            "fname": "John",
            "lname": "Doe"
            }
    }"""
    
    app_data = json.loads(json_data)
    
    schema = AppSchema()
    app = schema.load(app_data)
    
    print(app.data.person.fname)
    

    【讨论】:

    • 提示:您可以使用 make_object @post_load 方法从 BseSchema 继承所有模式。在每个模式中,将模型类设置为类属性:OBJECT_CLS = Person,在BaseSchema.make_object 中设置为:return self.OBJEC_CLS(**data)
    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多