【问题标题】:Passing string of int in BaseModel [closed]在 BaseModel 中传递 int 字符串 [关闭]
【发布时间】:2021-12-05 11:23:47
【问题描述】:

我正在尝试使用 BaseModel 的 POST 方法构建一个 fastAPI,以进行数据验证。 我的(简化)输入数据是一个 JSON,如下所示:

{   
"name": "test",
"a": {
    "b": {
        "c": {
            "0": "Fl"
        },
        "400": {
            "0": 0
        }
    },
    "d": {
        "400": {
            "0": 56.3,
            "1": 78.3,
            "2": 96.1,
            "3": 101.58
            }
        }
    }
}

当我尝试创建 BaseModel 时,PyCharm 通知我将 400、str(400) 或 '400' 作为键是错误的。所以我会有一个看起来像这样的类:

class D_0123(BaseModel):
    0: float
    1: float
    2: float
    3: float

class BD(BaseModel):
    400: Dict[D_0123]

class Item(BaseModel):
    name: str
    a: Dict[BD]

PyCharm 给我一个错误:“变量分配的非法目标”。 我知道 JSON 不能将 int 作为键,因为它们会自动转换为“int”。

所以我想知道我想做的事情是否可行?有解决办法吗?

感谢大家的宝贵时间!

祝你有美好的一天!

【问题讨论】:

  • 您的输入数据是有效的 JSON,PyCharm 不会抱怨这一点。请编辑发布 BaseModel 创建代码的问题,以便我们知道如何提供帮助。
  • @tzot 我添加了引发问题的 BaseModel 部分。

标签: python json fastapi pydantic


【解决方案1】:

pydantic(以及 FastAPI)利用的 Python 语法是:

class SomeName:
   attribute_name: type

BaseModel 超类可能有一个自定义元类(或自定义 __init_subclass__ 方法),它读取类属性的名称及其相关类型。 attribute_name 必须遵循 Python 的标识符语义,因此它必须以字母开头并以字母数字+下划线继续。

因此,我认为通常¹您无法使用不可接受的键作为标识符来利用“自动”验证,您必须使用自己的代码验证字段内容。
或者您可以更改约定,如果 pydantic 不忽略带下划线前缀的类成员,则任何由数字组成的键都以下划线开头。

¹我说“通常”是因为您可以替换:

class D_0123(BaseModel):
    0: float
    1: float
    2: float
    3: float

与:

D_0123 = type('D_0123', (BaseModel,), {"0": None, "1": None, "2": None, "3": None})
D_0123.__annotations__ = {"0": float, "1": float, "2": float, "3": float}

但我非常怀疑它是否会像您期望的那样工作;这取决于BaseModel 的定义以及在创建子类(即D_0123)期间完成了多少处理。

PS 另请参阅 FastAPI 文档中的 Bodies of arbitrary dicts。

【讨论】:

  • Python 3.9 并因此包含一个 typing.Annotated 类型,该类型也许可以用作 type() 的 dict 第三个参数中的值,但我使用 Python 3.8 并且无法对此进行测试。跨度>
  • 好的,我明白为什么它不起作用,但我不确定你添加的 2 行做了什么,以及在子类创建期间与处理量的联系。你能再解释一下吗?
  • type 使用三个参数调用:名称、超类、dict 是创建名称为name、子类化superclasses 并使用包含类成员的字典dict 的新类的方法(键属性名称,值属性值)。检查docs.python.org/3/library/functions.html#type 了解更多信息。为D_0123.__annotations__ 分配另一个dict 是如何在类成员具有类型注释时模仿Python 在幕后所做的。
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2021-06-17
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多