[Python-ideas] Callable Enum values

Ethan Furman ethan at stoneleaf.us
Sun Apr 16 14:14:34 EDT 2017


On 04/16/2017 01:24 AM, Steven D'Aprano wrote:
> On Fri, Apr 14, 2017 at 06:06:29PM -0700, Stephan Hoyer wrote:

>> One way that I've found myself using enums recently is for dispatching (as
>> keys in a dictionary) between different interchangeable functions or
>> classes.

[...]

> Given that wanting to use a function as the enumeration value is quite
> unusual in the first place, I don't think this belongs in the standard
> library.

I agree with D'Aprano: such unusual usage does not belong in the stdlib.

Fortunately, there is the Advanced Enumeration (aenum) library*:

--- 8< -----------------------------------------------------------------
from aenum import Enum, enum

class CallableEnum(Enum):

     def __new__(cls, *args, **kwds):
         member = object.__new__(cls)
         member._impl = args[0]
         if member._impl.__doc__ is not None:
             member._value_ = member._impl.__doc__
         else:
             member._value_ = repr(member._impl)
         return member

     def __call__(self, *args, **kwds):
         return self._impl(*args, **kwds)
--- 8< -----------------------------------------------------------------

and in use

--- 8< -----------------------------------------------------------------
class TestEnum(CallableEnum):

     @enum
     def hello(text):
         "a pleasant greeting"
         print('hello,', text)

     @enum
     def goodbye(text):
         print('goodbye,', text)

list(TestEnum)
# [
#  <TestEnum.hello: 'a pleasant greeting'>,
#  <TestEnum.goodbye: '<function goodbye at 0xb7264844>'>,
# ]

print(TestEnum.hello)
# TestEnum.hello

TestEnum.hello('how are you?')
# 'hello, how are you?'

TestEnum.goodbye('see you soon!')
# 'goodbye, see you soon!'
--- 8< -----------------------------------------------------------------

Note that it is possible to do the same thing using the stdlib Enum if 
you create your own decorator (it must return a class instance) and a 
slight rewrite of __new__ -- but I'll leave that as an exercise for the 
reader.

--
~Ethan~


* Disclosure:  I am the primary author of the stdlib Enum; I am also the 
author if the enum34 backport and the aenum library.

enum34: https://pypi.python.org/pypi/enum34
  aenum: https://pypi.python.org/pypi/aenum


More information about the Python-ideas mailing list