[英]Json serialization of nested dataclasses
I would need to take the question about json serialization of @dataclass
from Make the Python json encoder support Python's new dataclasses a bit further: consider when they are in a nested structure.我需要从Make the Python json 编码器进一步支持 Python 的新数据类中进一步考虑有关json serialization of @dataclass
问题:考虑它们何时处于嵌套结构中。
Consider:考虑:
import json
from attr import dataclass
from dataclasses_json import dataclass_json
@dataclass
@dataclass_json
class Prod:
id: int
name: str
price: float
prods = [Prod(1,'A',25.3),Prod(2,'B',79.95)]
pjson = json.dumps(prods)
That gives us:这给了我们:
TypeError: Object of type Prod is not JSON serializable
Note the above does incorporate one of the answers https://stackoverflow.com/a/59688140/1056563 .请注意,上面确实包含了答案之一 https://stackoverflow.com/a/59688140/1056563 。 It claims to support the nested case via the dataclass_json
decorator.它声称通过dataclass_json
装饰器支持嵌套案例。 Apparently that does not actually work.显然这实际上不起作用。
I also tried another of the answers https://stackoverflow.com/a/51286749/1056563 :我还尝试了另一个答案https://stackoverflow.com/a/51286749/1056563 :
class EnhancedJSONEncoder(json.JSONEncoder):
def default(s, o):
if dataclasses.is_dataclass(o):
return dataclasses.asdict(o)
return super().default(o)
And I created a helper method for it:我为它创建了一个辅助方法:
def jdump(s,foo):
return json.dumps(foo, cls=s.c.EnhancedJSONEncoder)
But using that method also did not effect the (error) result.但是使用该方法也不会影响(错误)结果。 Any further tips?任何进一步的提示?
import json
from dataclasses import dataclass, asdict
@dataclass
class Prod:
id: int
name: str
price: float
prods = [asdict(Prod(1, 'A', 25.3)), asdict(Prod(2, 'B', 79.95))]
pjson = json.dumps(prods)
print(pjson)
# [{"id": 1, "name": "A", "price": 25.3}, {"id": 2, "name": "B", "price": 79.95}]
You can use a pydantic
library.您可以使用pydantic
库。 From the example in documentation从文档中的示例
from pydantic import BaseModel
class BarModel(BaseModel):
whatever: int
class FooBarModel(BaseModel):
banana: float
foo: str
bar: BarModel
m = FooBarModel(banana=3.14, foo='hello', bar={'whatever': 123})
# returns a dictionary:
print(m.dict())
"""
{
'banana': 3.14,
'foo': 'hello',
'bar': {'whatever': 123},
}
"""
print(m.dict(include={'foo', 'bar'}))
#> {'foo': 'hello', 'bar': {'whatever': 123}}
print(m.dict(exclude={'foo', 'bar'}))
#> {'banana': 3.14}
This is actually not a direct answer but more of a reasonable workaround for cases where mutability is not needed (or desirable).这实际上不是一个直接的答案,而是对于不需要(或不需要)可变性的情况的更合理的解决方法。 The typing
based NamedTuple
looks and feels quite similar and is probably the inspiration behind the dataclass
.基于typing
的NamedTuple
看起来和感觉都非常相似,并且可能是dataclass
背后的灵感。 If serialization were needed it is likely presently the best alternative.如果需要序列化,它可能是目前最好的选择。
from typing import NamedTuple
class Prod(NamedTuple):
id: str
name: str
price: str
I made that as a drop-in replacement for the dataclass
based Prod
class and it works.我把它作为基于数据类的Prod
dataclass
的替代品,它可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.