You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI为何无法正确处理继承int与Enum的类型?

问题:FastAPI中自定义int继承的Enum无法解析路径参数

后端代码

from enum import Enum
from fastapi import FastAPI

class MyNumber(int, Enum):
    ONE = 1
    TWO = 2
    THREE = 3

app = FastAPI()

@app.get("/add/{a}/{b}")
async def get_model(a: MyNumber, b: MyNumber):
    return {"sum": a + b}

请求命令

curl -X 'GET' \
  'http://127.0.0.1:8000/add/2/3' \
  -H 'accept: application/json'

返回错误

{
  "detail": [
    {
      "loc": [
        "path",
        "a"
      ],
      "msg": "value is not a valid enumeration member; permitted: 1, 2, 3",
      "type": "type_error.enum",
      "ctx": {
        "enum_values": [
          1,
          2,
          3
        ]
      }
    },
    {
      "loc": [
        "path",
        "b"
      ],
      "msg": "value is not a valid enumeration member; permitted: 1, 2, 3",
      "type": "type_error.enum",
      "ctx": {
        "enum_values": [
          1,
          2,
          3
        ]
      }
    }
  ]
}

疑问

明明Swagger UI已经识别出可选值为整数,为什么还会报错?换成IntEnum就能正常工作,为什么必须这么做?


原因解析

核心差异:普通枚举 vs IntEnum

你自定义的MyNumber虽然同时继承了int和Enum,但它本质还是普通枚举类:

  • 枚举成员(比如MyNumber.TWO)是持有整数值的枚举对象,但并非真正的整数类型。用isinstance(MyNumber.TWO, int)测试会返回False。
  • FastAPI解析路径参数时,会把URL中的数字转换成Python原生int类型,而普通枚举的校验逻辑是判断传入值是否为枚举实例本身,而非匹配成员对应的数值,因此无法将int值识别为合法的枚举成员。

而IntEnum是Python专门设计的兼容整数的枚举类:

  • 它的成员同时也是int的实例(isinstance(MyIntNumber.TWO, int)返回True),完全兼容整数类型的特性。
  • 当FastAPI传入int类型的路径参数时,IntEnum可以直接通过数值匹配到对应的枚举成员,校验逻辑自然能正常通过。

从源码看区别

Python官方的IntEnum定义非常直接:

class IntEnum(int, Enum):
    """Enum where members are also (and must be) ints"""

它通过明确的继承顺序和内部元类逻辑,确保了枚举成员具备整数的所有特性,而普通的多继承枚举类无法实现这一点——Enum的元类会优先处理枚举逻辑,导致继承的int类型特性无法生效。


内容的提问来源于stack exchange,提问作者JHK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:36:07