枚举属性的类型注释

Type annotations for Enum attribute

我有这段代码:

import enum


class Color(enum.Enum):
    RED = '1'
    BLUE = '2'
    GREEN = '3'


def get_color_return_something(some_color):
    pass

如果我想我将从 Color 枚举中接收枚举属性(例如:Color.RED),我该如何正确地向此函数中的 some_color 变量添加类型注释?

def get_color_return_something(some_color: Color):
    pass

提示颜色 class 的类型应该有效:

def get_color_return_something(some_color: Color):
    print(some_color.value)

以下将适用于 Python 3.9/PyCharm

from enum import Enum
from typing import Optional, Union


class Color(Enum):
    RED: int = 1
    GREEN: int = 2


def guess_color(x: Union[Color.RED, Color.GREEN]) -> Optional[ValueError]:
    if x == Color.RED:
        print("Gotcha!")
    else:
        return ValueError(f"It's not {Color.RED}")


guess_color(Color.RED)

另一种奇怪语法变通方法是使用引用的前向引用语法将枚举成员指定为枚举class的类型(根据PEP 484 ):

from enum import Enum


class ETest(Enum):
    EXAMPLE: 'ETest' = "example"  <--- forward referenced type


def example() -> ETest:
    return ETest.EXAMPLE


print(type(ETest.EXAMPLE.value))

<class 'str'>

在下图中,很明显 PyCharm 中突出显示的警告不再存在。

作为参考,下面是 PyCharm 将 EXAMPLE 成员指定为 <str> 类型的申诉截图:

我不喜欢这种方法,但它确实消除了警告。

您可以尝试使用类型提示文字的选项。

official PEP8 documentation我们知道:

Literal it's type that can be used to indicate to type checkers that the corresponding variable or function parameter has a value equivalent to the provided literal (or one of several literals)

因此,如果您需要为函数参数使用某些特定值,这将是最佳选择之一。但是由于枚举值的类型,这种方法不会像我们预期的那样完全起作用。每个值都有一个枚举类型 class。这意味着对于下面的代码示例,我们将能够将 Color.GREEN 作为函数参数。所以这样的解决方案将只是开发人员的信息,而不是函数参数的强制性规则。

class Color(enum.Enum):
    RED = '1'
    BLUE = '2'
    GREEN = '3'

print(type(Color.RED)  # will return <enum 'Color'>

代码示例:

from enum import Enum
from typing import Literal


class Color(Enum):
    RED = '1'
    BLUE = '2'
    GREEN = '3'

def some_function(some_color: Literal[Color.RED, Color.BLUE]) -> None:
    pass

第二个选项是@ibarrond 从 提供的完全正确的解决方案,只有 class 类型提示。

some_color: Color

所以在这里您可以根据需要选择要使用的选项。

从我的角度来看,我们可以尝试为开发人员指定可能的 Enum 值,以便在我们对功能的要求中更加明确。