从Python 3.7开始,有一种叫做数据类的东西:
from dataclasses import dataclass
@dataclass
class Foo:
x: str
但是,以下操作失败:
>>> import json
>>> foo = Foo(x="bar")
>>> json.dumps(foo)
TypeError: Object of type Foo is not JSON serializable
如何使json.dumps()
的{{1}}实例编码为json objects?
答案 0 :(得分:16)
就像您可以为datetime
objects或Decimals添加对JSON编码器的支持一样,您还可以提供自定义编码器子类来序列化数据类:
Foo
答案 1 :(得分:10)
如果可以使用该库,则可以使用dataclasses-json。这是一个示例:
from dataclasses import dataclass
from dataclasses_json import dataclass_json
@dataclass_json
@dataclass
class Foo:
x: str
foo = Foo(x="some-string")
foo_json = foo.to_json()
它还支持嵌入式数据类-如果您的数据类具有键入为另一个数据类的字段-如果所涉及的所有数据类都具有@dataclass_json
装饰器。
答案 2 :(得分:10)
要实现该目标,有两种选择,每种选择都暗示着哪种方法最适合您的需求:
import dataclasses
import json
@dataclass.dataclass
class Foo:
x: str
foo = Foo(x='1')
json_foo = json.dumps(dataclasses.asdict(foo)) # '{"x": "1"}'
将其选择回数据类实例并非易事,因此您可能希望访问该答案https://stackoverflow.com/a/53498623/2067976
from dataclasses import field
from marshmallow_dataclass import dataclass
@dataclass
class Foo:
x: int = field(metadata={"required": True})
foo = Foo(x='1') # Foo(x='1')
json_foo = foo.Schema().dumps(foo) # '{"x": "1"}'
# Back to class instance.
Foo.Schema().loads(json_foo) # Foo(x=1)
作为marshmallow_dataclass
的奖励,您可以在字段本身上使用验证,当有人使用该模式从json反序列化对象时,将使用该验证。
from dataclasses import dataclass
from dataclasses_json import dataclass_json
@dataclass_json
@dataclass
class Foo:
x: int
foo = Foo(x='1')
json_foo = foo.to_json() # Foo(x='1')
# Back to class instance
Foo.from_json(json_foo) # Foo(x='1')
此外,除了这一点,棉花糖数据类确实为您进行了类型转换,而dataclassses-json(ver .: 0.5.1)却忽略了这一点。
遵循已接受的miracle2k答案并重复使用自定义json编码器。
答案 3 :(得分:2)
您是否只能使用dataclasses.asdict()
函数来转换数据类
一个命令?像这样:
>>> @dataclass
... class Foo:
... a: int
... b: int
...
>>> x = Foo(1,2)
>>> json.dumps(dataclasses.asdict(x))
'{"a": 1, "b": 2}'
答案 4 :(得分:2)
我建议使用 to_json()
方法为您的数据类创建一个父类:
import json
from dataclasses import dataclass, asdict
@dataclass
class Dataclass:
def to_json(self) -> str:
return json.dumps(asdict(self))
@dataclass
class YourDataclass(Dataclass):
a: int
b: int
x = YourDataclass(a=1, b=2)
x.to_json() # '{"a": 1, "b": 2}'
如果您有其他功能要添加到所有数据类中,这将特别有用。
答案 5 :(得分:1)
使用字典解包on Reddit可以找到更简单的答案
>>> from dataclasses import dataclass
>>> @dataclass
... class MyData:
... prop1: int
... prop2: str
... prop3: int
...
>>> d = {'prop1': 5, 'prop2': 'hi', 'prop3': 100}
>>> my_data = MyData(**d)
>>> my_data
MyData(prop1=5, prop2='hi', prop3=100)
答案 6 :(得分:0)
好的,这是我在类似情况下所做的。
创建一个自定义字典工厂,将嵌套数据类转换为字典。
定义我的工厂(数据): return dict(x for x in data if x[1] is not None)
如果 foo 是您的@dataclass,那么只需提供您的字典工厂以使用“myfactory()”方法:
fooDict = asdict(foo, dict_factory=myfactory)
将 fooDict 转换为 json
fooJson = json.dumps(fooDict)
这应该可行!!