pydantic无法腌制私人属性

发布于 2025-02-10 18:36:23 字数 1258 浏览 1 评论 0原文

我试图将一个私有属性(不能腌制)设置为我的模型:

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 "pydantic\main.py", line 349, in pydantic.main.BaseModel.__init__
  File "pydantic\main.py", line 419, in pydantic.main.BaseModel._init_private_attributes
  File "pydantic\fields.py", line 1180, in pydantic.fields.ModelPrivateAttr.get_default
  File "pydantic\utils.py", line 657, in pydantic.utils.smart_deepcopy
  File "...\lib\copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle '_thread.lock' object

似乎失败了,因为lock无法腌制(或复制)。此外,由于某种原因,Pydantic似乎试图复制私人属性。我在文档中查看,找不到模型属性来覆盖这一点。另外,配置nuterary_types_loweredcopy_on_model_validation没有效果。我还尝试使用privateattr(default = lock()),但这无济于事。

有趣的是,如果属性不是私有的,则该示例有效(通过underscore_attrs_are_private = false in config> config)。

我想将此属性作为私人。如何设置一个不能腌制到Pydantic模型的私人属性?

I tried to set a private attribute (that cannot be pickled) to my model:

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()

But this produces an error:

Traceback (most recent call last):
  File ".../example.py", line 9, in <module>
    x = MyModel()
  File "pydantic\main.py", line 349, in pydantic.main.BaseModel.__init__
  File "pydantic\main.py", line 419, in pydantic.main.BaseModel._init_private_attributes
  File "pydantic\fields.py", line 1180, in pydantic.fields.ModelPrivateAttr.get_default
  File "pydantic\utils.py", line 657, in pydantic.utils.smart_deepcopy
  File "...\lib\copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle '_thread.lock' object

It seems it fails because Lock cannot be pickled (or copied). Furthermore, it seems Pydantic tries to copy private attributes for some reason. I looked in the docs and could not find a model property to override this. Also, the configs arbitrary_types_allowed or copy_on_model_validation have no effect. I also tried to use PrivateAttr(default=Lock()) but that did not help.

Interestingly, the example works if the attribute was not private (by setting underscore_attrs_are_private = False in Config).

I would like to have this attribute as private. How can I set a private attribute that cannot be pickled to Pydantic Model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一生独一 2025-02-17 18:36:23

在进行了更多调查后,我自己找到了答案。似乎可以使用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()

I found the answer myself after doing some more investigation. It seems this can be solved using 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()

Furthermore, it seems the copying is done in the BaseModel init only. One can also set the attribute later:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文