JSON 使用棉花糖序列化 - 跳过 None 属性
JSON serialization using Marshmallow - skip None attributes
我正在使用 Marshmallow 将我的决定 class 的实例发送到 JSON。但是,这也会转储 None
的属性,例如我的属性 score
将在 JSON 中转换为 null
。之后我无法使用相同的方法再次阅读 JSON。
https://repl.it/repls/VoluminousMulticoloredFacts
最后一行是当前失败的地方。我需要在加载期间不将 None
转储到 JSON 或跳过 null
:
import json
from marshmallow import Schema, fields, post_load
json_data = """{
"appid": "2309wfjwef",
"strategy": "First Strategy"
}"""
# Output class definition
class Decision(object):
def __init__(self, appid = None, strategy = None, score = None):
self.appid = appid
self.strategy = strategy
self.score = score
class DecisionSchema(Schema):
appid = fields.Str()
strategy = fields.Str()
score = fields.Int()
@post_load
def make_decision(self, data):
return Decision(**data)
# Deserialization into object
dec_json = json.loads(json_data)
schema = DecisionSchema()
dec = schema.load(dec_json).data
print(dec.strategy)
# Dump results back to JSON
schema = DecisionSchema()
out = schema.dumps(dec)
print(out.data)
# Load back from dump
schema = DecisionSchema()
dec = schema.load(out).data
#print(dec.strategy) # returns error currently
棉花糖开发团队的“官方”回答可以在错误追踪器的 this comment 中找到:
使用post_dump
方法。
from marshmallow import Schema, fields, post_dump
class BaseSchema(Schema):
SKIP_VALUES = set([None])
@post_dump
def remove_skip_values(self, data, **kwargs):
return {
key: value for key, value in data.items()
if value not in self.SKIP_VALUES
}
class MySchema(BaseSchema):
foo = fields.Field()
bar = fields.Field()
sch = MySchema()
sch.dump({'foo': 42, 'bar': None}).data # {'foo': 42}
正如我在 a further comment 中指出的那样,有一个缺点:当字段的 allow_none
为 True
时,它也会删除 None
。
正如我在上面的评论中指出的那样,如果您使用
class Meta:
fields = (
'field1', 'field2'
)
ordered = True
为了解决这个问题,我使用了这个:
# Remove None fields
@pre_dump
def remove_skip_values(self, data):
return {
key: value for key, value in data.items()
if value is not None
}
这适用于我的对象字典
我正在使用 Marshmallow 将我的决定 class 的实例发送到 JSON。但是,这也会转储 None
的属性,例如我的属性 score
将在 JSON 中转换为 null
。之后我无法使用相同的方法再次阅读 JSON。
https://repl.it/repls/VoluminousMulticoloredFacts
最后一行是当前失败的地方。我需要在加载期间不将 None
转储到 JSON 或跳过 null
:
import json
from marshmallow import Schema, fields, post_load
json_data = """{
"appid": "2309wfjwef",
"strategy": "First Strategy"
}"""
# Output class definition
class Decision(object):
def __init__(self, appid = None, strategy = None, score = None):
self.appid = appid
self.strategy = strategy
self.score = score
class DecisionSchema(Schema):
appid = fields.Str()
strategy = fields.Str()
score = fields.Int()
@post_load
def make_decision(self, data):
return Decision(**data)
# Deserialization into object
dec_json = json.loads(json_data)
schema = DecisionSchema()
dec = schema.load(dec_json).data
print(dec.strategy)
# Dump results back to JSON
schema = DecisionSchema()
out = schema.dumps(dec)
print(out.data)
# Load back from dump
schema = DecisionSchema()
dec = schema.load(out).data
#print(dec.strategy) # returns error currently
棉花糖开发团队的“官方”回答可以在错误追踪器的 this comment 中找到:
使用post_dump
方法。
from marshmallow import Schema, fields, post_dump
class BaseSchema(Schema):
SKIP_VALUES = set([None])
@post_dump
def remove_skip_values(self, data, **kwargs):
return {
key: value for key, value in data.items()
if value not in self.SKIP_VALUES
}
class MySchema(BaseSchema):
foo = fields.Field()
bar = fields.Field()
sch = MySchema()
sch.dump({'foo': 42, 'bar': None}).data # {'foo': 42}
正如我在 a further comment 中指出的那样,有一个缺点:当字段的 allow_none
为 True
时,它也会删除 None
。
正如我在上面的评论中指出的那样,如果您使用
class Meta:
fields = (
'field1', 'field2'
)
ordered = True
为了解决这个问题,我使用了这个:
# Remove None fields
@pre_dump
def remove_skip_values(self, data):
return {
key: value for key, value in data.items()
if value is not None
}
这适用于我的对象字典