我试图为我的模型设置一个私有属性(不能pickle):
from threading import Lock
from pydantic import BaseModel
class MyModel(BaseModel):
class Config:
underscore_attrs_are_private = True
_lock: Lock = Lock() # This cannot be copied
x = MyModel()
但是这会产生一个错误:
Traceback (most recent call last):
File ".../example.py", line 9, in <module>
x = MyModel()
File "pydanticmain.py", line 349, in pydantic.main.BaseModel.__init__
File "pydanticmain.py", line 419, in pydantic.main.BaseModel._init_private_attributes
File "pydanticfields.py", line 1180, in pydantic.fields.ModelPrivateAttr.get_default
File "pydanticutils.py", line 657, in pydantic.utils.smart_deepcopy
File "...libcopy.py", line 161, in deepcopy
rv = reductor(4)
TypeError: cannot pickle '_thread.lock' object
似乎它失败了,因为Lock
不能被pickle(或复制)。此外,Pydantic似乎出于某种原因试图复制私有属性。我看了看文档,找不到一个模型属性来覆盖这个。同时,配置arbitrary_types_allowed
和copy_on_model_validation
也没有影响。我也尝试使用PrivateAttr(default=Lock())
,但没有帮助。
Config
中设置underscore_attrs_are_private = False
),该示例也可以工作。
我希望这个属性是私有的。如何设置不能pickle到Pydantic Model的私有属性?
经过一番调查,我自己找到了答案。这似乎可以使用default_factory
:
from threading import Lock
from pydantic import BaseModel, PrivateAttr
class MyModel(BaseModel):
class Config:
underscore_attrs_are_private = True
_lock = PrivateAttr(default_factory=Lock)
x = MyModel()
此外,似乎复制只在BaseModel
init中完成。还可以稍后设置该属性:
from threading import Lock
from pydantic import BaseModel, PrivateAttr
class MyModel(BaseModel):
class Config:
underscore_attrs_are_private = True
_lock: Lock
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._lock = Lock()
x = MyModel()