简体   繁体   English

枚举 class 实例的属性值的类型注释

[英]Type annotation for values of attributes of an Enum class instance

In python, I have the following instance of the Enum class:在 python 中,我有以下枚举 class 的实例:

class Colour(Enum):
    Red = "1"
    Blue = "2"
    Green = "3"

I have a function that takes a value of an attribute of this class, ie one of Colour.Red.value , Colour.Blue.value or Colour.Green.value :我有一个 function,它采用此 class 的属性值,即Colour.Red.valueColour.Blue.valueColour.Green.value之一:

def myfunc(input_str):
    return(input_str)

How do I define the type annotation for input_str in this case?在这种情况下,如何为input_str定义类型注释?

Pylance returns a warning when using input_str: Literal[Colour.Red.value, Colour.Blue.value, Colour.Green.value] : "Type arguments for "Literal" must be None, a literal value (int, bool, str, or bytes), or an enum value". Pylance 在使用input_str: Literal[Colour.Red.value, Colour.Blue.value, Colour.Green.value] : "Type arguments for "Literal" must be None, a literal value (int, bool, str,或字节),或枚举值”。 I understand from PEP-0586 that Literal[Colour.Red, Colour.Blue, Colour.Green] would be allowed, however that does not seem to fit my use case.我从PEP-0586了解到Literal[Colour.Red, Colour.Blue, Colour.Green]是允许的,但这似乎不适合我的用例。

There is no need to artificially restrict yourself and demand for functions to only accept enum values specifically.没有必要人为地限制自己,要求函数专门只接受枚举

If you want myfunc to do something with the value of the member of the Colour enum, you should still let it take the enum member as an argument:如果你想让myfuncColour枚举成员的值做一些事情,你仍然应该让它把枚举成员作为参数:

from enum import Enum
from typing import Literal


class Colour(Enum):
    Red = "1"
    Blue = "2"
    Green = "3"


def f(colour: Colour) -> None:
    print(colour.value.center(5, "-"))


def g(colour: Literal[Colour.Blue, Colour.Green]) -> None:
    print(colour.value * 5)


f(Colour.Red)
g(Colour.Green)

Output: Output:

--1--
33333

Moreover, if you want, you can mix in str specifically as the supertype for your enum members.此外,如果需要,您可以将str作为枚举成员的超类型专门混入 Then they can essentially be treated as strings for most intents and purposes.然后,出于大多数意图和目的,它们基本上可以被视为字符串。

In this code I don't access the member .value :在此代码中,我不访问成员.value

from enum import Enum
from typing import Literal


class Colour(str, Enum):  # notice the order of inheritance
    Red = "1"
    Blue = "2"
    Green = "3"


def f(colour: Colour) -> None:
    print(colour.center(5, "-"))  # `colour` is of type `str`


def g(colour: Literal[Colour.Blue, Colour.Green]) -> None:
    print(colour * 5)  # `colour` is of type `str`


f(Colour.Red)
g(Colour.Green)

Same output.同样是 output。

The order of inheritance actually guarantees that all str methods will be present and work as expected on all enum members. inheritance 的顺序实际上保证了所有str方法都将存在并按预期在所有枚举成员上工作。

It would surprise me, if you could not use those enum members anywhere in place of "regular" str objects.如果您不能在任何地方使用这些枚举成员来代替“常规” str对象,我会感到惊讶。

You can verify the type, if you do isinstance(Colour.Red, str) .如果执行isinstance(Colour.Red, str) ,则可以验证类型。 The members are now subtypes of str .成员现在是str的子类型。 If you want some other concrete data type for the members, you can use that too.如果你想为成员使用一些其他的具体数据类型,你也可以使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM