是否可以在 pydantic 模型的自定义方法上使用自定义或其他库的装饰器 class

Is it possible to use custom or other libraries' decorators on a custom method of a pydantic model class

我正在使用 Pydantic 的 BaseModel 创建我的作品 class。除了带有验证器的方法之外,我还有自定义方法。我需要将 functools 中的 singledispatchmethod 装饰器与自定义函数一起使用。例如,

class Foo(pydantic.BaseModel):
    name: str
    bar: int
    baz: int

    @functools.singledispatchmethod
    def handle(self, command: Command) -> CommandResult:
        pass

    @celery.task
    def add(a: int, b: int):
        time.sleep(10)
        print("Sum is: ", a+b)

但是,使用 singledispatchmethod 时会抛出以下错误

File "/models.py", line 56, in <module>
   class Foo(pydantic.BaseModel):
File "pydantic/main.py", line 323, in pydantic.main.ModelMetaclass.__new__
File "pydantic/fields.py", line 411, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 342, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 456, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 670, in pydantic.fields.ModelField.populate_validators
File "pydantic/validators.py", line 715, in find_validators
RuntimeError: no validator found for <class 'functools.singledispatchmethod'>, see `arbitrary_types_allowed` in Config

以同样的方式,我也想在其中一种自定义方法上使用 Celery 的任务装饰器。

并不是每个装饰器都会导致这种行为。在这种情况下,singledispatchmethod 是一个描述符 class,默认情况下 pydantic 不会对其进行处理。

但您可以使用 keep_untouched 模型配置设置。摘自documentation

keep_untouched

a tuple of types (e.g. descriptors) for a model's default values that should not be changed during model creation and will not be included in the model schemas. Note: this means that attributes on the model with defaults of this type, not annotations of this type, will be left alone.

class Foo(BaseModel):
    name: str
    bar: int

    @functools.singledispatchmethod
    def handle(self, command: str) -> str:
        pass

    class Config:
        keep_untouched = (functools.singledispatchmethod,)