python - Pydantic,允许解析属性或将其传递给构造函数,但使其不可变

标签 python python-3.x pydantic

我正在尝试制作一个 Pydantic 模型,该模型大部分是可变的,但我希望其中一个成员是不可变的。

型号

# Built In
from datetime import datetime

# 3rd Party
from pydantic import BaseModel
from pydantic import Field # https://pydantic-docs.helpmanual.io/usage/schema/#field-customisation

class Processor(BaseModel):
    """ Pydantic model for a Processor object within the database. """
    class Config:
        """
        Model Configuration: https://pydantic-docs.helpmanual.io/usage/model_config/
        """
        extra = 'forbid'
        allow_mutation = True # This allows mutation, cool
        validate_assignment = True
        underscore_attrs_are_private = True
    model: str
    created_at: str = Field(default_factory=datetime.utcnow().isoformat) # I want to make sure that this can be passed but not assignable
    updated_at: str
    version: int = 0
    expires: Optional[int] = None

我的目标是允许从对象(或默认对象)解析created_at,但防止在创建模型后对其进行分配。

示例

example_object = {
    "model": "foobar_model",
    "created_at": "2020-12-22T15:35:06.262454+00:00",
    "updated_at": "2020-12-22T15:35:06.262454+00:00",
    "version": 2,
    "expires": None
}
processor = Processor.parse_obj(example_object)
processor.version = 3 # This should be allowed
processor.created_at = datetime.utcnow().isoformat() # This I want to fail

相关但不是我要找的 - GitHub:Is there a way to have a single field be static and immutable with pydantic


我最终通过以下问题的答案解决了这个问题: https://github.com/samuelcolvin/pydantic/issues/2217

最佳答案

以下内容不起作用:

您可以将私有(private)属性与属性装饰器结合使用。私有(private)属性不包含在模型字段中,但可以通过属性访问。

from pydantic import BaseModel, PrivateAttr


class Processor(BaseModel):
    """ Pydantic model for a Processor object within the database. """
    class Config:
        """
        Model Configuration: https://pydantic-docs.helpmanual.io/usage/model_config/
        """
        extra = 'forbid'
        allow_mutation = True # This allows mutation, cool
        validate_assignment = True
        underscore_attrs_are_private = True
    model: str
    _created_at: str = PrivateAttr(default_factory=datetime.utcnow().isoformat)
    _is_date_set: bool = PrivateAttr(default_factory=lambda: False)
    updated_at: str
    version: int = 0
    expires: Optional[int] = None

    @property
    def created_at(self):
        return self._created_at

    @create_at.setter
    def created_at(self, val):
        if self._is_date_set:
            raise AttributeError('The created_at attribute has already been set')
        self._is_date_set = True
        self._created_at = x

关于python - Pydantic,允许解析属性或将其传递给构造函数,但使其不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65415197/

相关文章:

python - 当句子的所有关键字都包含在字典中时,如何将句子与字典关联?

python - "import pkg.module"是否相当于 2.7 中 pkg/__init.py__ 中的 "import module"而不是 3.5 中的 0x104567910?

python-3.x - 如何更改 Pydantic 默认 __root__ 示例

python - 使用 apply 函数在 pandas 中创建一个具有舍入值的新列

python - 如何对每列中的所有值求和并将每列除以求和值

python-3.x - Tensorflow中的欧氏距离,转换矩阵

python - 从 pydantic 数据模型的打印和调用中隐藏变量(例如 'password')

python - Pydantic:根据其他字段的值在验证器中使字段为 None

javascript - Python读取http : html page as seen in browser - with javascripts results

python - 如何从内存中向 Tesseract 提供图像