Эта статья не супер в глубине. Я только что обнаружил крутой модуль в библиотеке Standard Python и хотел поделиться им, чтобы вызвать ваш интерес. Если вы столкнетесь с какими -либо проблемами и у вас есть какие -либо вопросы, я рад изо всех сил, чтобы помочь вам пройти через это!
Использование модуля Enum’s Python
Я работал над упражнением на Упражнения Это было связано с поиском лучшей покерной руки, и я оказался с множеством «волшебных ценностей», плавающих вокруг. Когда я говорю «магическую ценность», я имею в виду, что твердое кодируемая постоянная, которая должна иметь какое-то семантическое значение. В этом конкретном случае у меня были игровые карты, которые могли бы принять одно из 13 различных конкретных значений, и у некоторых из этих значений были имена. И Тогда У меня были покерные руки, которые получали оценку, и эти различные типы рук также имели внутренние ценности, где некоторые руки были лучше, чем другие.
Моя первая итерация была дополнительной волшебной и выглядела примерно так:
if self.is_straight() and self.is_flush(): return 8 elif self.biggest_group() == 4: # 4 of a Kind return 7 elif self.is_full_house(): return 6 elif self.is_flush(): return 5 elif self.is_straight(): return 4 elif self.biggest_group() == 3: # 3 of a kind return 3 elif self.is_two_pair(): return 2 elif self.biggest_group() == 2: # One pair return 1 else: # High Card return 0
Это было странно и заставило меня показывать код с кодовой точки зрения. Но я позволил этому пройти. Затем я написал этот код:
if value == "A": self.value = 14 elif value == "K": self.value = 13 elif value == "Q": self.value = 12 elif value == "J": self.value = 11 else: self.value = int(value)
Больше волшебных чисел! Я смутно помнил, что у Питона был enum
Модуль в его стандартной библиотеке, и я также смутно помнил, что enums
должны были быть полезны для ситуаций, когда у вас есть конкретные категории/типы, которые может принять значение. Итак, я провел некоторое исследование. Оказывается, они на самом деле даже круче, чем я думал.
enum
Модуль имеет кучу разных типов enums
Но, поскольку я много делал сортировки, сравнивая и относительный рейтинг, а также переходил между этими и нормальными числами, я выбрал Intenum
Анкет Это просто означает, что enum
Значения будут целыми. Но как это выглядит?
Вы можете определить перечисление с помощью функционального синтаксиса (так же, как вы создаете экземпляр класса или создать тип ждемца
), или вы можете создать его с помощью синтаксиса класса. Вы увидите оба в этой статье, по разным причинам.
Сначала я покажу функциональную оценку для покерных рук. Я иду по этому пути, потому что мне все равно, какие цифры. Я просто хочу прояснить относительный рейтинг.
from enum import IntEnum Score = IntEnum('Score', [ 'HIGH_CARD', 'PAIR', 'TWO_PAIR', 'THREE_OF_A_KIND', 'STRAIGHT', 'FLUSH', 'FULL_HOUSE', 'FOUR_OF_A_KIND', 'STRAIGHT_FLUSH', ])
И это все, что нам нужно. Теперь мы можем увидеть их относительные ценности и сравнить их!
>>> Score.STRAIGHT.value 5 >>> Score.FOUR_OF_A_KIND > Score.THREE_OF_A_KIND True >>> Score.FLUSH < Score.HIGH_CARD False
Это позволяет нам семантизировать (мое новое слово, спасибо!) Наш код выше:
if self.is_straight() and self.is_flush(): return Score.STRAIGHT_FLUSH elif self.biggest_group() == 4: return Score.FOUR_OF_A_KIND elif self.is_full_house(): return Score.FULL_HOUSE elif self.is_flush(): return Score.FLUSH elif self.is_straight(): return Score.STRAIGHT elif self.biggest_group() == 3: return Score.THREE_OF_A_KIND elif self.is_two_pair(): return Score.TWO_PAIR elif self.biggest_group() == 2: return Score.PAIR else: return Score.HIGH_CARD
Намного более читаемо! Один из способов, которым вы знаете, что мы делаем что -то правильно, это то, что я смог удалить объяснения комментариев для некоторых из менее четких условий, не потеряв какую -либо читабельность вообще. Круто, верно?
Теперь давайте посмотрим на другой случай со значениями Face Card. Для этого я использовал синтаксис класса, потому что я хотел добавить немного больше функциональности. Подробнее об этом через минуту. Вот стартовый код.
class FaceCard(IntEnum): """Numeric values of face cards""" JACK = 11 QUEEN = 12 KING = 13 ACE = 14
Теперь мы можем использовать его как обычный номер, но это Имен!
Входные данные были предоставлены как строки символов: "Ах"
для Ace of Hearts, "8c"
Для 8 клубов и т. Д. Я начал с определения такой карты:
class Card: def __init__(self, label): self.suit = label[-1] value = label[:-1] if value == "J": self.value = FaceCard.JACK elif value == "Q": self.value = FaceCard.QUEEN elif value == "K": self.value = FaceCard.KING elif value == "A": self.value = FaceCard.ACE else: self.value = int(value) def __lt__(self, other): return self.value < other.value
__init__
Метод инициализация экземпляра, а __lt__
Метод рассказывает, как эти объекты ведут себя вокруг <
оператор. Теперь мы можем сравнить их так:
>>> king = Card("KS") # King of Spades >>> three = Card("3S") # Three of Spades >>> three < king True
Несмотря на то, что ценность для короля на самом деле является Facecard. Король
, он сравнивает использование его целочисленного значения, поэтому я могу относиться к нему как к нормальному числу для большинства вещей! Перечисления крутые!
Для получения дополнительной информации, Стандартные библиотечные документы действительно хороши.
Бонус: обратно в струны!
Я думал enum
было круто. А потом я узнал, что мне нужно преобразовать значения моей карты обратно в их закодированные строки для вывода. Как выясняется, перечисления имеют два основных свойства: имя
, что похоже на «ключ», и значение
Анкет Проверьте это удивительность:
# The same FaceCard class as before: class FaceCard(IntEnum): """Numeric values of face cards""" JACK = 11 QUEEN = 12 KING = 13 ACE = 14 # This is new: # Define a custom method to call when a case gets "stringified" def __str__(self): return self.name[0]
Теперь в нашем классе карт:
class Card: # ... def __str__(self): return str(self.value) + self.suit
И потому что мы определили пользовательский __str__
Метод для Facecard
То, как мы это сделали, этот код будет работать независимо от того, является ли карта лицевой картой или нет!
>>> eight = Card("8H") >>> ace = Card("AD") >>> eight.value 8 >>> eight.suit "H" >>> ace.value FaceCard.ACE >>> ace.suit "D" >>> str(eight) "8H" # str(eight) == str(8) + "H" >>> str(ace) "AD" # str(ace) == str(FaceCard.ACE) + "D" # str(FaceCard.ACE) == "ACE"[0] == "A"
Верно?? ПРАВИЛЬНО?!?! Я имею в виду, насколько элегантно вы можете получить?
Я хочу знать, как ты Используется enum
до. Вы нашли аккуратный вариант использования? Есть ли другие драгоценные камни в enum
модуль, которого я еще не обнаружил?
Оригинал: “https://dev.to/rpalo/giving-meaning-to-magic-numbers-with-python-enums-21od”