python - Pydantic - 如何子类化内置类型
问题描述
我正在尝试创建一个期望接收毫秒而不是秒的 timedelta 子类,但它目前无法正常工作。
我是在反对谷物吗?Pydantic 是否有“正确”的方法来实现这一目标?或者我是否需要以某种方式告诉 Pydantic 这MillisecondTimedelta
只是一个timedelta
..
from datetime import timedelta
from pydantic import BaseModel
class MillisecondTimedelta(timedelta):
@classmethod
def __get_validators__(cls):
# timedelta expects seconds
yield lambda v: v / 1000
yield cls
class MyModel(BaseModel):
td: MillisecondTimedelta
data = {
"td": 7598040,
}
print(MyModel(**data))
结果是:
Traceback (most recent call last):
File "main.py", line 14, in <module>
class MyModel(BaseModel):
File "pydantic/main.py", line 262, in pydantic.main.ModelMetaclass.__new__
File "pydantic/fields.py", line 315, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 284, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 362, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 541, in pydantic.fields.ModelField.populate_validators
File "pydantic/class_validators.py", line 255, in pydantic.class_validators.prep_validators
File "pydantic/class_validators.py", line 238, in pydantic.class_validators.make_generic_validator
File "/usr/lib/python3.8/inspect.py", line 3105, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
File "/usr/lib/python3.8/inspect.py", line 2854, in from_callable
return _signature_from_callable(obj, sigcls=cls,
File "/usr/lib/python3.8/inspect.py", line 2384, in _signature_from_callable
raise ValueError(
ValueError: no signature found for builtin type <class '__main__.MillisecondTimedelta'>
解决方案
如文档页面__get_validators__()
所示,您需要生成一个或多个验证器。
修改后的类报告如下;问题是 Pydantic 理解(对于 timedelta 字段) int 并浮动为 seconds (source)。
class MillisecondTimedelta(timedelta):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if any(isinstance(v, t) for t in (int, float)):
return cls(milliseconds=v)
现在一切都应该正常工作。
>>> data = {"td": 1000}
>>> print(MyModel(**data))
td=MillisecondTimedelta(seconds=1)
编辑:没有自定义类和验证器,可以使用函数来编辑要分配给类构造函数的值;需要装饰此功能,如此处所示
class MyModel(BaseModel):
td: timedelta
@validator('td')
def convert_to_ms(cls, v):
return v / 1000
此解决方案也有效:
>>> data = {"td": 3000}
>>> print(MyModel(**data))
td=datetime.timedelta(seconds=3)
推荐阅读
- ios - Dart 颤振 Admob 在 Ios 中不起作用。我大约 1 周前发布了我的应用程序
- c++ - 间接需要指针操作数错误
- c++ - 在 C++ 中不使用数组或最小值/最大值计算测试成绩平均值
- aem - 仅当存在时才在 Sightly/HTL 中添加属性 (AEM)
- deep-learning - 为什么小权重有助于深度神经网络(正则化)
- javascript - 条卡元素输入不显示
- python - 使用 Python ctypes 调用 rs232.c 时如何解决分段错误问题?
- c - 有人可以帮我解决那个C问题吗?当我尝试运行它不返回任何东西
- python-3.x - 如何使用 GTK PrintOperation 打印图像
- python - matplotlib 多个 xticklabel 用于两个 colluns 的条形图