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

如何无需枚举让类实例作为泛型值通过Mypy检查?

问题现象

我发现一个实用的小特性:如果把类实例赋值给枚举成员,那么在Literal或泛型类型中使用这个实例时,mypy不会报错;但直接用普通变量的话,就会触发"Variable not allowed in type expression"错误。用这种方式标识对象类型在某些场景下很方便,示例代码如下:

from enum import Enum
from typing import Literal, Generic

class MyKlass():
    pass

my_val = MyKlass()

class MyEnum(Enum):
     val = my_val

Literal[MyEnum.val]  # mypy 不报错
Literal[my_val]      # mypy 报错:"Variable not allowed in type expression"

基于这个特性,我实现了让泛型接受任意值的写法:

class MyEnum(Enum):
    val = my_val

class MyClass(Generic[T]):
    pass

MyClass[MyEnum.val]  # 无问题

更优实现方式

不用额外定义枚举类,直接用typing.Final标记变量为常量即可。mypy会把Final修饰的变量认定为编译时常量表达式,允许它出现在Literal或泛型类型参数中,代码更简洁:

from typing import Final, Literal, Generic

class MyKlass():
    pass

# 用Final标记变量为不可变常量
my_val: Final[MyKlass] = MyKlass()

# 直接使用变量,mypy不报错
Literal[my_val]

class MyClass(Generic[T]):
    pass

# 泛型中直接使用Final变量
MyClass[my_val]

原理说明

mypy对类型表达式的核心要求是必须为常量表达式:

  • 枚举成员本身就是不可变的常量,天然符合要求
  • Final标记的变量会被mypy判定为不可修改的常量,同样满足类型表达式的规则

这种方式省去了冗余的枚举定义,同时完美契合“避免将值作为函数参数传入,聚焦静态类型检查”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:05:06