在 Python 类型中将 enum 转换为 Literal 类型别名

fed*_*ber 10 python enums typing

有没有一种方法可以在Python中对函数或变量进行类型注释,从而允许从枚举的属性形成枚举或文字?

from enum import Enum
from typing import Literal


class State(str, Enum):
    ENABLED = "enabled"
    DISABLED = "disabled"

def is_enabled(state: State | Literal["enabled", "disabled"]) -> bool:
    if isinstance(state, str):
        state = State(state)
    return state == State.ENABLED
Run Code Online (Sandbox Code Playgroud)

换句话说,有没有一种方法可以获取别名而Literal["enabled", "disabled"]不必重写枚举的所有键?

fun*_*man 8

恐怕没有这样的办法。首先想到的是迭代枚举的值来构建文字类型是行不通的,因为Literal不能包含任意表达式。因此,您不能明确指定它:

# THIS DOES NOT WORK
def is_enabled(state: State | Literal[State.ENABLED.value, State.DISABLED.value]) -> bool:
    ...
Run Code Online (Sandbox Code Playgroud)

GitHub 上有一个未解决的问题以及相关讨论。基本上,您可以为每个 Enum 都硬编码文字,但在这种情况下,您需要根据 Enum 更新来更新它,有一天它会变得混乱。因此,我要么坚持使用State | str注释,要么只是State期望你的函数只接受枚举。

另外,考虑到您不需要显式创建 Enum 对象来测试其值,您可以按照"enabled" == State.ENABLED我在评论中提到的那样编写。