如何使用Python输入提示Enum,str

unftdfkk  于 2023-05-19  发布在  Python
关注(0)|答案(2)|浏览(145)

使用Python 3.8并给出这些行:

from enum import Enum

class Stuff1(str, Enum):
    A = "A"
    B = "B"
    C = "C"

class Stuff2(int, Enum):
    A = 1
    B = 2
    C = 3
def encoder(value: <?>) -> str:
    return value.value.lower()

a = encoder(Stuff1.A) # Will work as expected because Stuff1 is expected as input
b = encoder(Stuff2.B) # Will not work but will not be a warning inside my IDE if <?> is Enum

如何键入hint包含字符串值的枚举来代替<?>,是否只授权Stuff1内部编码器参数?我希望这个值是一个枚举,但我希望这个枚举只有字符串值。实现这一目标的最佳途径是什么?
注意:是的,在Python 3.11中存在StrEnum,但我在Python 3.8下
NB 2:我应该能够在不知道Enum中的值的情况下输入我的参数,所以Literal不适合我。
我目前有:

from enum import Enum

def encoder(value: Enum) -> str:
    if isinstance(value, str):
        return value.value.lower()
    raise Exception("Non string value as input")

a = encoder(Stuff1.A) # Will work as expected and my IDE will be happy because Stuff1 is expected as input
b = encoder(Stuff2.B) # Will not be a warning inside my IDE as Stuff2 is an Enum too, but contains integers.

但是我只需要字符串值Enums,所以对于简单的东西来说,这段代码看起来有点沉重。

w41d8nur

w41d8nur1#

您可以执行以下操作:

from enum import Enum
from typing import Literal

class Stuff1(str, Enum):
    A = "A"
    B = "B"
    C = "C"

class Stuff2(int, Enum):
    A = 1
    B = 2
    C = 3

def encoder(value: Literal["A","B","C"]) -> str:
    if isinstance(value, str):
        return value.lower()
    raise Exception("Non string value as input")

a = encoder(Stuff1.A.value)

Literal在这里很合适。它会告诉IDE encoder需要有限数量的可能字符串。
但是,它稍微修改了您的流,因为您现在必须将枚举成员值而不是枚举成员传递给encoder

0vvn1miw

0vvn1miw2#

看起来您需要使用str作为value的类型。Enum不会起作用,甚至StrEnum可能也不行(您需要更改枚举的基数,并且它有不同的行为)。
我还认为,说“这个函数接受任何枚举值”几乎没有什么用处--看起来你是在试图强制执行编码标准,而不是静态类型检查,除非你把值转换回它们的枚举?
另一个选择(如果你依赖于一些共享行为,而不是所有值都是字符串)是派生你自己的StrEnum类基(PyPI上有一个StrEnum package会有所帮助)。

相关问题