[英]pydantic `json_encoders` for builtin types (float, int, etc)
I'm having some unexpected behavior with json encoding of fields like float
, int
, etc. using pydantic.我在使用 pydantic 对
float
、 int
等字段进行 json 编码时遇到了一些意外行为。 Here is the documentation for json encoding, for reference.这里是json编码的文档,供参考。
As an example, this model seems to encode complex
just fine, but ignores my float
field.例如,这个 model 似乎可以很好地编码
complex
,但忽略了我的float
字段。
import pydantic as pd
class Model(pd.BaseModel):
class Config:
arbitrary_types_allowed=True
json_encoders = {
float: lambda x: 'test',
complex: lambda x: 'test'
}
d1:float
d2:complex
m = Model(d1=1.0, d2=1j)
m.json()
# '{"d1": 1.0, "d2": "test"}'
Can anyone shine light on this behavior and point me in the right direction?谁能阐明这种行为并为我指明正确的方向?
My use case is a custom encoder to detect when a float
is numpy.inf
and then write it to "Infinity"
in json rather than the illegal default value of Infinity
as encoded by the json
package.我的用例是一个自定义编码器,用于检测
float
何时为numpy.inf
,然后将其写入 json 中的"Infinity"
,而不是json
package 编码的Infinity
的非法默认值。
Thanks for your help!谢谢你的帮助!
The reason behind why your custom json_encoder not working for float
type is pydantic uses json.dumps()
for serialization.您的自定义 json_encoder 不适用于
float
类型的原因是pydantic使用json.dumps()
进行序列化。 If any type is serializable with json.dumps()
it will not use cutom json_encoder for those types.如果任何类型可使用
json.dumps()
进行序列化,则不会对这些类型使用 cutom json_encoder。
And come to the complex
type it's not serializable by json.dumps()
that's why it's using the custom json_encoder you have provided.来到
complex
类型,它不能被json.dumps()
序列化,这就是它使用您提供的自定义 json_encoder 的原因。
If you still want to use custom json_encoder you can use orjson as suggested by pydantic.如果您仍想使用自定义 json_encoder,您可以按照 pydantic的建议使用 orjson。
Custom JSON (de)serialisation 自定义 JSON(反)序列化
Sample Code:示例代码:
def orjson_dumps(v, *, default):
for key, value in v.items():
if isinstance(value, float):
v[key] = 'test'
elif isinstance(value, complex):
v[key] = 'test'
# orjson.dumps returns bytes, to match standard json.dumps we need to decode
return orjson.dumps(v, default=default).decode()
class Model(BaseModel):
class Config:
arbitrary_types_allowed=True
json_dumps = orjson_dumps
json_loads = orjson.loads
d1:float
d2:complex
m = Model(d1=1.0, d2=1j)
m.json() # {"d1":"test","d2":"test"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.