如何基于列表生成pydantic模型Literal字段?可否通过枚举实现?
可以通过枚举的方式解决该需求,且是非常主流的实现方案。
首先需要说明你给出的示例代码本身不可运行:Literal的泛型参数必须传入固定字面量,不能直接传入列表变量,运行时会触发类型错误。
枚举实现方案
1. 手动定义枚举(最推荐,静态类型检查友好)
同时继承str和Enum的枚举类可以直接作为pydantic字段类型,既支持传枚举成员也支持传对应字符串字面量,校验逻辑完全符合需求:
from pydantic import BaseModel from enum import Enum # 定义枚举类 class OptsEnum(str, Enum): FOO = 'foo' BAR = 'bar' class MyModel(BaseModel): select_one: OptsEnum
校验效果:
MyModel(select_one='foo')校验通过MyModel(select_one='baz')抛出校验错误
2. 动态生成枚举(适合可选值动态变化的场景)
如果可选值列表是动态生成的,不需要手动写枚举成员,可以用Enum的动态构造方法:
from pydantic import BaseModel from enum import Enum opts = ['foo', 'bar'] # 动态生成字符串类型的枚举类 OptsEnum = Enum('OptsEnum', [(v.upper(), v) for v in opts], type=str) class MyModel(BaseModel): select_one: OptsEnum
补充:非枚举的Literal实现方案
如果你不想用枚举,Python 3.11及以上版本支持Literal的解包写法,也能实现从序列推导可选值的效果(注意必须用常量元组,不能用列表):
from pydantic import BaseModel from typing import Literal opts = ('foo', 'bar') class MyModel(BaseModel): select_one : Literal[*opts]
该写法的缺点是静态类型检查工具对动态解包的Literal支持度不如枚举。
内容的提问来源于stack exchange,提问作者Erysol
相关产品推荐
相关产品推荐

