New submission from Mohith:
Addendum to issue 18042.
I've had a use case where I wanted to allow reverse lookups (i.e.
value-to-member lookup) for my enum.Enum that was decorated via @enum.unique.
In such a case, I would add my own class method that performs the logic. E.g.
an unoptimized copy-and-paste-able example for use via python3 interactive
shell:
import datetime
import enum
@enum.unique
class DayOfWeek(enum.Enum):
SUNDAY = 0 # Sunday is '0' according to strftime('%w')
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6 # Saturday is '6' according to strftime('%w')
@classmethod
def reverse_lookup(cls, value):
for _, member in cls.__members__.items():
if member.value == value:
return member
raise LookupError
today_value = int(datetime.date.today().strftime('%w'))
today = DayOfWeek.reverse_lookup(today_value)
print('Today is', today.name.title())
---
(Aside: it seems like an optimized version that uses a cached lookup dictionary
is inconvenient to implement in that it involves storing the cache in a global
variable or a closure or a descriptor attribute or etc. [unless there's a
simple recommended approach of which I am just unaware].)
I think use cases for reverse lookup would not be uncommon. For example, an
IntEnum subclass decorated via @enum.unique is a great candidate (as is any
simple hashable/equatable value type). I am unsure of the proper interface, but
I am thinking that passing a boolean argument to enum.unique should enable the
usage of a special __lookup__ metaclass property for optimized reverse lookups.
I am thinking a possible (untested) enhancement to enum.unique along the lines
of:
class EnumMeta(type):
...
_reverse_lookup_ = None
@property
def __lookup__(cls):
if cls._reverse_lookup_ is None:
raise AttributeError('Reverse lookup unsupported.')
return MappingProxyType(cls._reverse_lookup_)
def unique(enumeration, reverse_lookup=False):
...
reverse_lookup = {} if reverse_lookup else None
for name, member in enumeration.__members__.items():
...
if reverse_lookup is not None:
reverse_lookup[member.value] = member
...
if reverse_lookup is not None:
enumeration._reverse_lookup_ = reverse_lookup
return enumeration
--
components: Library (Lib)
messages: 239038
nosy: barry, eli.bendersky, ethan.furman, mmuddasani
priority: normal
severity: normal
status: open
title: Allow reverse lookup (value-to-member) for Enum sublcasses decorated
with @enum.unique
type: enhancement
versions: Python 3.4, Python 3.5, Python 3.6
___
Python tracker
<http://bugs.python.org/issue23751>
___
___
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com