Вы должны перегрузить крюк _missing_
.Все экземпляры WeekDay
создаются при первом определении класса;WeekDay(date(...))
- это операция индексирования, а не операция создания, а __new__
первоначально ищет уже существующие значения, связанные с целыми числами от 0 до 6. В противном случае он вызывает _missing_
, в который вы можете преобразовать date
объект в такое целое число.
class WeekDay(Enum):
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6
@classmethod
def _missing_(cls, value):
if isinstance(value, date):
return cls(value.weekday())
return super()._missing_(value)
Несколько примеров:
>>> WeekDay(date(2019,3,7))
<WeekDay.THURSDAY: 3>
>>> assert WeekDay(date(2019, 4, 1)) == WeekDay.MONDAY
>>> assert WeekDay(date(2019, 4, 3)) == WeekDay.MONDAY
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
(Примечание: _missing_
недоступен до Python 3.6.)
До 3.6 кажется, что вы можете переопределить EnumMeta.__call__
, чтобы выполнить ту же проверку, но я не уверен, будут ли это непредвиденные побочные эффекты.(Рассуждение о __call__
всегда заставляет мою голову немного кружиться.)
# Silently convert an instance of datatime.date to a day-of-week
# integer for lookup.
class WeekDayMeta(EnumMeta):
def __call__(cls, value, *args, **kwargs):
if isinstance(value, date):
value = value.weekday())
return super().__call__(value, *args, **kwargs)
class WeekDay(Enum, metaclass=WeekDayMeta):
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6