python - примеры - шифрование mongodb




Как сравнить строку с перечислением python? (2)

Возможно, что auto() вернет имя члена перечисления в качестве его значения (которое находится в разделе auto документов 1 :

>>> class AutoName(Enum):
...     def _generate_next_value_(name, start, count, last_values):
...         return name
...

>>> class Ordinal(AutoName):
...     NORTH = auto()
...     SOUTH = auto()
...     EAST = auto()
...     WEST = auto()
...

>>> list(Ordinal)
[<Ordinal.NORTH: 'NORTH'>, <Ordinal.SOUTH: 'SOUTH'>, <Ordinal.EAST: 'EAST'>, <Ordinal.WEST: 'WEST'>]

1 Для этого требуется версия Python 3.6 или aenum 2.0 2 ( aenum работает с Pythons старше 2.7).

2 Раскрытие: я являюсь автором Enum , enum34 и библиотеки Advanced Enumeration ( aenum ) .

Я только что обнаружил существование базового класса Enum в Python и пытаюсь представить, как он может быть полезен для меня

Допустим, я определяю состояние светофора:

from enum import Enum, auto

class Signal(Enum):
    red = auto()
    green = auto()
    orange = auto()

Допустим, я получаю информацию от некоторой подсистемы в моей программе в виде строки, представляющей имя цвета, например brain_detected_colour = "red" .

Как мне сравнить эту строку с моими сигналами светофора?

Очевидно, brain_detected_colour is Signal.red это False , потому что Signal.red не является строкой.

Signal(brain_detected_colour) is Signal.red ошибкой ValueError: 'red' is not a valid Signal .


Один не создает экземпляр Enum . Синтаксис Signal(foo) используется для доступа к элементам Enum по значению, которые не предназначены для использования, когда они являются auto() .

Однако можно использовать строку для доступа к членам Enum так же, как можно получить доступ к значению в dict , используя квадратные скобки:

Signal[brain_detected_colour] is Signal.red

Другой возможностью было бы сравнить строку с name члена Enum:

# Bad practice:
brain_detected_colour is Signal.red.name

Но здесь мы не проверяем идентичность между членами Enum, а сравниваем строки, поэтому лучше использовать тест на равенство:

# Better practice:
brain_detected_colour == Signal.red.name

(Сравнение идентичности между строками сработало благодаря интернированию строк , на которое лучше не полагаться. Спасибо @mwchase и @Chris_Rands за то, что они меня об этом узнали.)

Еще одной возможностью было бы явно установить значения элементов в качестве их имен при создании Enum:

class Signal(Enum):
    red = "red"
    green = "green"
    orange = "orange"

(См. Этот ответ для метода, чтобы автоматизировать это.)

Тогда Signal(brain_detected_colour) is Signal.red будет действительным.





python-3.6