首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pydantic生成动态模型

使用pydantic生成动态模型
EN

Stack Overflow用户
提问于 2021-02-12 16:29:51
回答 2查看 2.1K关注 0票数 2

我正在尝试使用Python的pydantic库创建一个动态模型。我的输入数据是一个常规的dict。但是,dict的内容(读取:其密钥)可能会有所不同。

我想知道如何动态创建一个依赖于dict内容的pydantic模型?

我用两个不同的dict (inputs1inputs2)创建了一个玩具示例。让我们假设名为strategy的嵌套dict可能不同。基于strategy/name,我提前知道strategy中将存在哪些字段。我需要创建基于strategy/namepydantic模型。

代码语言:javascript
复制
from pydantic import BaseModel

inputs1 = {
    "universe": {"name": "test_universe", "ccy": "USD"},
    "price_src": "csv",
    "strategy": {"name": "test_strat1"},
}
inputs2 = {
    "universe": {"name": "test_universe", "ccy": "USD"},
    "price_src": "csv",
    "strategy": {"name": "test_strat2", "periods": 10},
}


class Universe(BaseModel):
    name: str
    ccy: str = "EUR"


strategy_name = "test_strat2"

if strategy_name == "test_strat1":
    inputs = inputs1

    class Strategy(BaseModel):
        name: str


elif strategy_name == "test_strat2":
    inputs = inputs2

    class Strategy(BaseModel):
        name: str
        periods: int


class StaticModel(BaseModel):
    universe: Universe
    price_src: str = "csv"
    strategy: Strategy


static_model = StaticModel(**inputs)

如果strategy_name ==“test_strat1”,我的预期输出:

代码语言:javascript
复制
universe=Universe(name='test_universe', ccy='USD') price_src='csv' strategy=Strategy(name='test_strat1')

如果strategy_name ==“test_strat2”,我的预期输出:

代码语言:javascript
复制
universe=Universe(name='test_universe', ccy='USD') price_src='csv' strategy=Strategy(name='test_strat2', periods=10)

我在考虑使用pydanticcreate_model函数,但是我不知道如何动态定义fields

EN

回答 2

Stack Overflow用户

发布于 2021-02-12 16:43:42

对于pydantic模型的动态创建,可以使用create_model。如下所示:

代码语言:javascript
复制
from pydantic import create_model

d = {"strategy": {"name": "test_strat2", "periods": 10}}

Strategy = create_model("Strategy", **d["strategy"])

print(Strategy.schema_json(indent=2))

输出:

代码语言:javascript
复制
{
  "title": "Strategy",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "default": "test_strat2",
      "type": "string"
    },
    "periods": {
      "title": "Periods",
      "default": 10,
      "type": "integer"
    }
  }
}
票数 2
EN

Stack Overflow用户

发布于 2021-12-22 17:27:32

您可以使用带有key=(type, ...) (字面意思是3个点)的create_model来指定该字段没有默认值。以下是基于您所需的工作代码。

代码语言:javascript
复制
from pydantic import BaseModel, create_model

...

if strategy_name == "test_strat1":
    inputs = inputs1
    Strategy = create_model('Strategy', name=(str, ...))

elif strategy_name == "test_strat2":
    inputs = inputs2
    Strategy = create_model('Strategy', name=(str, ...), periods=(int, ...))


class StaticModel(BaseModel):
    universe: Universe
    price_src: str = "csv"
    strategy: Strategy


print(Strategy.schema_json(indent=2))

strategy_name == "test_strat1"的输出

代码语言:javascript
复制
{
  "title": "Strategy",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "name"
  ]
}

而对于strategy_name == "test_strat2"

代码语言:javascript
复制
{
  "title": "Strategy",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "type": "string"
    },
    "periods": {
      "title": "Periods",
      "type": "integer"
    }
  },
  "required": [
    "name",
    "periods"
  ]
}

可以在以下位置找到相关的Pydantic文档:https://pydantic-docs.helpmanual.io/usage/models/#dynamic-model-creation

您可以在文档中看到:

没有

  • foo=(str, ...) - defaults
  • bar=123类型的123.

类型的foo属性的bar属性

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66168517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档