Аннотации типа Python для значения Enum
У меня есть этот кусок кода:
import enum
class Color(enum.Enum):
RED = '1'
BLUE = '2'
GREEN = '3'
def get_color_return_something(some_color):
pass
Как правильно добавить аннотации к some_color
varaible в этой функции, если я предполагаю получить значение из перечисления Color (например: Color.RED
)?
6 ответов
Тип, намекающий на класс Color, должен работать:
def get_color_return_something(some_color: Color):
print(some_color.value)
Вы можете попробовать использовать вариант с подсказкой типа Literal.
Из официальной документации PEP8 мы знаем, что:
Литерал - это тип, который можно использовать для указания средствам проверки типов, что соответствующая переменная или параметр функции имеет значение, эквивалентное предоставленному литералу (или одному из нескольких литералов).
Так что в случае, если вам нужно использовать какие-то конкретные значения для аргумента функции, это будет один из лучших вариантов. Но этот подход не будет работать полностью, как мы ожидали, из-за типа значений Enum. Каждое значение будет иметь тип класса Enum. Это означает, что для приведенного ниже примера кода мы сможем использовать 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 из сообщения выше, с подсказкой типа класса.
some_color: Color
Так что здесь вы можете выбрать вариант работы в зависимости от ваших потребностей.
С моей точки зрения, мы можем попытаться указать возможные значения Enum для разработчиков, чтобы быть более ясными в наших требованиях к функции.
Следующее будет работать с Pyton 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)
Другой странный синтаксический обходной путь - указать члены Enum как тип класса Enum с использованием синтаксиса цитирования с прямой ссылкой (согласно 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>
введите как имеет смысл:
Я не поклонник этого подхода , но это действительно избавиться от предупреждения.
Вы можете напечатать имя и значение следующим образом:
import enum
class Color(enum.Enum):
RED = '1'
BLUE = '2'
GREEN = '3'
def get_color_return_something(some_color):
print(some_color.name)
print(some_color.value)
get_color_return_something(Color.RED)
# RED
# 1