当 pydantic 模型是另一个模型的嵌套子模型时,排除该模型上的字段

2024-01-15

我有一个 pydantic 模型,我想动态排除其中的字段。

我可以通过覆盖来做到这一点dict在模型上运行,以便它可以采用我的自定义标志,例如:

class MyModel(BaseModel):
  field: str

  def dict(self, **kwargs):
    if ('exclude_special_fields' in kwargs):
       super().dict(exclude={"field": True}, **kwargs)

    super().dict(**kwargs)

但是,如果我的模型是另一个模型的子模型,则这不起作用.dict呼吁它:

class AnotherModel(BaseModel):
  models: List[MyModel]

AnotherModel(models=[...]).dict(exclude_special_fields=True) # does not work

这是因为当MyModel.dict()被调用时,它不会使用与父级相同的参数来调用。

我可以写一个dict也覆盖父模型以指定任何子组件的排除(例如exclude={"models": {"__all__": {"field": True}}}),但在我的现实世界示例中,我有许多使用这个子模型的父模型,并且我不想为每个子模型编写一个覆盖。

无论如何,我可以确保子模型知道何时排除字段吗?

额外的背景信息

额外的上下文对于问题来说并不完全重要,但我想要这样做的原因是排除模型上的某些字段(如果它从 API 调用返回)。


查看源代码后,我看不出有任何方法可以通过提供的专门 kwarg 轻松实现这一点。这dict函数是递归的,不支持任意参数。

现在,我能够将一些东西组合在一起,但是……这太糟糕了。这是使用执行的pydantic==1.10.7.

我在想我们可以在排除参数中应用一个特殊的标志值来提供一些东西来触发排除逻辑。这变得比我预期的更棘手,因为它需要了解对象的完整结构以及准确地如何索引排除的字段。列表上还发生了一些奇怪的标准化,这导致提供的值在函数调用过程中发生变化。

这是我能得到的最好的结果(警告未经过彻底测试)。我们创建一个字典,它在每次查找时返回自身,暴露__all__作为排除字段。这将允许我们的密钥传递给每个模型,并传递给子对象进行评估。

EXCLUDED_SPECIAL_FIELDS = "exclude_special_fields"

class _ExclusionDict(dict):
    def __init__(self):
        super().__init__({"__all__": {EXCLUDED_SPECIAL_FIELDS: True}})

    def get(self, key):
        return self


ExcludeSpecial = _ExclusionDict()


class SpecialExclusionBaseModel(BaseModel):
    _special_exclusions: set[str]

    def dict(self, **kwargs):
        exclusions = getattr(self.__class__, "_special_exclusions", None)
        exclude = kwargs.get("exclude")
        if exclusions and exclude and EXCLUDED_SPECIAL_FIELDS in exclude:
            return {
                k: v
                for k, v in super().dict(**kwargs).items()
                if k not in exclusions
            }
        return super().dict(**kwargs)

通过这个基类,我们可以提供一个名为的类字段_special_exclusions来指示我们想要排除哪些字段ExcludeSpecial实例提供为excludekw 参数。

在一些初步测试中,这似乎适用于嵌套层次结构,包括字典和列表。这里可能存在需要解决的错误,但希望这对其他人来说是一个很好的起点。

class MyModel(SpecialExclusionBaseModel):
    _special_exclusions = {"field"}
    field: str

class AnotherModel(BaseModel):
    models: list[MyModel]

class AnotherAnotherModel(BaseModel):
    models: dict[str, AnotherModel]


model = MyModel(field=1)
another = AnotherAnotherModel(models={"test": AnotherModel(models=[model])})
print(another.dict(exclude=ExcludeSpecial))
{'models': {'test': {'models': [{}]}}}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当 pydantic 模型是另一个模型的嵌套子模型时,排除该模型上的字段 的相关文章

  • sklearn 估计器管道的参数无效

    我正在实现 O Reilly 书中的一个示例 Python 机器学习简介 使用 Python 2 7 和 sklearn 0 16 我正在使用的代码 pipe make pipeline TfidfVectorizer LogisticRe
  • 为什么需要在 Python 方法中显式使用“self”参数? [复制]

    这个问题在这里已经有答案了 当在 Python 中的类上定义方法时 它看起来像这样 class MyClass object def init self x y self x x self y y 但在其他一些语言中 例如 C 您可以使用
  • scipy.optimize on pandas dataframe

    我试图搜索它 但结果很差 有人可以向我解释一下如何在 Pandas DataFrame 上执行 optimize minimize 以便最小化 DataFrame 中的类别和结果列之间的错误 考虑这个例子 import pandas as
  • 如何使用一个模型中间层的输出作为另一个模型的输入?

    我训练一个模型A并尝试使用中间层的输出name layer x 作为模型的附加输入B 我尝试像 Keras 文档一样使用中间层的输出https keras io getting started faq how can i obtain th
  • 类型错误:“datetime.datetime”和“str”的实例之间不支持“>”

    我是 python 日期和时间类型的新手 我有一个日期值 date 2018 11 10 10 55 31 00 00 我需要检查该日期值是否超过 90 天 我试过 from datetime import datetime from da
  • 如何在Windows中的Python 3.9下pip安装pickle?

    我需要pickle https docs python org 3 9 library pickle html module pickle包安装在我的下面Python 3 9在 Windows 10 下 我尝试过的 当尝试与pip inst
  • App Engine NDB:如何访问属性的 verbose_name

    假设我有这个代码 class A ndb Model prop ndb StringProperty verbose name Something m A m prop a string value 当然 现在如果我打印 m prop 它会
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • 如何从hdfs读取文件[重复]

    这个问题在这里已经有答案了 我在 project1目录下的hadoop文件系统中有一个文本文件名mr txt 我需要编写 python 代码来读取文本文件的第一行 而不将 mr txt 文件下载到本地 但我无法从 hdfs 打开 mr tx
  • 为什么 re.findall 在查找字符串中的三元组项时不具体。 Python

    所以我有四行代码 seq ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA OR 0 re findall r ATG 9 TAA TAG TGA seq 首先让我解释一下我正在尝试做什么 如果这令人困惑
  • 正在使用 PIL 保存损坏的图像

    我遇到一个问题 操作图像像素导致保存损坏的图像 因此 我使用 PIL 打开图像 然后将其转换为 NumPy 数组 image Image open myimage png np image np asarray image 然后 我转置图像
  • 在请求中设置端口

    我正在尝试利用cgminer使用 Python 的 API 我对利用requests图书馆 我了解如何做基本的事情requests but cgminer想要更具体一点 我想缩小 import socket import json sock
  • 高级描述熊猫

    有没有像 pandas 那样更高级的功能 通常我会继续这样 r pd DataFrame np random randn 1000 columns A r describe 我会得到一份很好的总结 就像这样 A count 1000 000
  • 将 window.location 传递给 Flask url_for

    我正在使用 python 在我的页面上 当匿名用户转到登录页面时 我想将一个变量传递到后端 以便它指示用户来自哪里 发送 URL 因此 当用户单击此锚链接时 a href Sign in a 我想发送用户当前所在页面的当前 URL
  • 更改 Matplotlib 投影轴的背景颜色

    我正在尝试使用 Cartopy 创建一个图形 该图形需要在未投影的轴上绘制投影轴 这是一个尽可能简单的代码版本 它将轴上的内容替换为背景颜色 import matplotlib pyplot as plt import cartopy cr
  • python Recipe:列出最接近等于值的项[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 考虑像这样的列表 0 3 7 10 12 15 19 21 我想获得最接近任何值的最近的最小数字 所以如果我通过4 我会得到3 如果我
  • 两种 ODE 求解器之间的差异

    我想知道 两者之间有什么区别ODEINT and solve ivp用于求解微分方程 它们之间有什么优点和缺点 f1 solve ivp f 0 1 y0 y0 is the initial point f2 odeint f y0 0 1
  • MoviePY 无法在 Windows 上检测 ImageMagick 二进制文件

    我刚买了一台新笔记本电脑 想要设置MoviePY在那新的Windows 64x Python3 7 0 机器 我对所有内容都进行了三次检查 但是当涉及到我的代码的文本部分时 它向我抛出了这个错误 OSError MoviePy Error
  • 如何同时接受int和float类型的输入?

    我正在制作一个货币转换器 如何让 python 同时接受整数和浮点数 我就是这样做的 def aud brl amount From to ER 0 42108 if amount int if From strip aud and to
  • Biopython 可以执行 Seq.find() 来解释歧义代码吗

    我希望能够在 Seq 对象中搜索考虑歧义代码的子序列 Seq 对象 例如 以下内容应该是正确的 from Bio Seq import Seq from Bio Alphabet IUPAC import IUPACAmbiguousDNA

随机推荐