1. When and where to use enums?当你有一个变量,它接受一组有限的可能值。在
例如,一周中的几天:class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 72. Why do we need enum? What are the advantages?枚举是有利的,因为它们给常量起了一个名字,这使得代码更具可读性;而且由于单个成员不能被反弹,使得Python枚举成为半常量(因为Enum本身仍然可以反弹)。
除了可读性更好的代码外,调试也更容易,因为您可以看到名称和值,而不仅仅是值
可以将所需的行为添加到枚举中
例如,任何使用过datetime模块的人都知道,datetime和{}对于一周中的几天有两种不同的表示:0-6或1-7。我们可以向Weekday枚举中添加一个方法,从datetime或{}实例中提取日期并返回匹配的enum成员:
^{pr2}$
3. What exactly is Enum?Enum是一个type,其成员是命名常量,它们都属于(或应该)一个逻辑值组。到目前为止,我已经为以下对象创建了Enums:- the days of the week
- the months of the year
- US Federal Holidays in a year
FederalHoliday是我最复杂的;它使用this recipe,并且有方法返回给定年份的实际假日发生日期,如果所讨论的日期是假日,则返回下一个工作日(或跳过的天数范围包括假日或周末),以及一年的完整日期集。这里是: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, occurrence=None):
self.__doc__ = doc
self.type = type
self.month = month
self.day = day
self.occurrence = occurrence
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.occurrence * 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
注意事项:增强的xrange(支持一系列日期)也是自定义的,但我不认为我已经将其包含在任何地方;下次我修补它时,我会将它填充到我的dbf包中。