Python enum, ¿cuándo y dónde usar?
enums python-3.4 (2)
1. ¿Cuándo y dónde usar enums?
- Cuando tiene una variable que toma uno de un conjunto limitado de valores posibles.
Por ejemplo, los días de la semana:
class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
2. ¿Por qué necesitamos enum? ¿Cuáles son las ventajas?
Los enumerados son ventajosos porque dan un nombre a una constante, lo que hace que el código sea más legible; y porque los miembros individuales no pueden ser rebote, haciendo que Python Enums sea semi-constante (porque el propio
Enum
aún podría rebotar).Además de un código más legible, la depuración también es más fácil ya que se ve un nombre junto con el valor, no solo el valor
El comportamiento deseado se puede agregar a Enums
Por ejemplo, como sabe cualquier persona que haya trabajado con el módulo de datetime
y datetime
, la datetime
y la date
tienen dos representaciones diferentes para los días de la semana: 0-6 o 1-7. En lugar de hacer un seguimiento de eso nosotros mismos, podemos agregar un método al enum de Weekday para extraer el día de la instancia de date
y datetime
y devolver el miembro enum coincidente:
@classmethod
def from_date(cls, date):
return cls(date.isoweekday())
3. ¿Qué es exactamente Enum?
Enum es un tipo cuyos miembros se denominan constantes, todos pertenecen (o deberían) a un grupo lógico de valores. Hasta ahora he creado
Enum
s para:- the days of the week - the months of the year - US Federal Holidays in a year
FederalHoliday
es mi más complejo; usa esta receta y tiene métodos para devolver la fecha real en que se realizan las vacaciones para el año dado, el siguiente día hábil si el día en cuestión es festivo (o el intervalo de días omitidos incluye las vacaciones o los fines de semana) y el conjunto completo de fechas por un año. Aquí está:
class FederalHoliday(AutoEnum):
NewYear = "First day of the year.", ''absolute'', Month.JANUARY, 1
MartinLutherKingJr = "Birth of Civil Rights leader.", ''relative'', Month.JANUARY, Weekday.MONDAY, 3
President = "Birth of George Washington", ''relative'', Month.FEBRUARY, Weekday.MONDAY, 3
Memorial = "Memory of fallen soldiers", ''relative'', Month.MAY, Weekday.MONDAY, 5
Independence = "Declaration of Independence", ''absolute'', Month.JULY, 4
Labor = "American Labor Movement", ''relative'', Month.SEPTEMBER, Weekday.MONDAY, 1
Columbus = "Americas discovered", ''relative'', Month.OCTOBER, Weekday.MONDAY, 2
Veterans = "Recognition of Armed Forces service", ''relative'', Month.NOVEMBER, 11, 1
Thanksgiving = "Day of Thanks", ''relative'', Month.NOVEMBER, Weekday.THURSDAY, 4
Christmas = "Birth of Jesus Christ", ''absolute'', Month.DECEMBER, 25
def __init__(self, doc, type, month, day, occurance=None):
self.__doc__ = doc
self.type = type
self.month = month
self.day = day
self.occurance = occurance
def date(self, year):
"returns the observed date of the holiday for `year`"
if self.type == ''absolute'' or isinstance(self.day, int):
holiday = Date(year, self.month, self.day)
if Weekday(holiday.isoweekday()) is Weekday.SUNDAY:
holiday = holiday.replace(delta_day=1)
return holiday
days_in_month = days_per_month(year)
target_end = self.occurance * 7 + 1
if target_end > days_in_month[self.month]:
target_end = days_in_month[self.month]
target_start = target_end - 7
target_week = list(xrange(start=Date(year, self.month, target_start), step=one_day, count=7))
for holiday in target_week:
if Weekday(holiday.isoweekday()) is self.day:
return holiday
@classmethod
def next_business_day(cls, date, days=1):
"""
Return the next `days` business day from date.
"""
holidays = cls.year(date.year)
years = set([date.year])
while days > 0:
date = date.replace(delta_day=1)
if date.year not in years:
holidays.extend(cls.year(date.year))
years.add(date.year)
if Weekday(date.isoweekday()) in (Weekday.SATURDAY, Weekday.SUNDAY) or date in holidays:
continue
days -= 1
return date
@classmethod
def year(cls, year):
"""
Return a list of the actual FederalHoliday dates for `year`.
"""
holidays = []
for fh in cls:
holidays.append(fh.date(year))
return holidays
Notas :
Date
es de mi paquete dbfel
xrange
mejorado (compatible con un rango de fechas) también es personalizado, pero no creo haberlo incluido en ningún lado; Lo rellenaré en mi paquetedbf
próxima vez que lo retoque.Divulgación: soy el autor de Python stdlib
Enum
, elenum34
backport y la biblioteca de Enumeración avanzada (aenum
) .
Python 3.4.0 introdujo enum
, he leído el documento pero sigo sin saber su uso. Desde mi punto de vista, enum es un tipo de namedtuple
largo namedtuple
extendido, que puede no ser cierto. Entonces esto es lo que quiero saber sobre enum:
- ¿Cuándo y dónde usar enum?
- ¿Por qué necesitamos enum? ¿Cuáles son los advatages?
- ¿Qué es exactamente enum?
PEP 435 ("Agregar un tipo Enum a la biblioteca estándar de Python") detrás de la introducción de Enum
en Python tiene muchos ejemplos de cómo los autores pretendían que se usara.
Más comentarios aquí .