Enums are great. They allow you cleanly define a set of statically defined options.
One way that I've found myself using enums recently is for dispatching (as keys in a dictionary) between different interchangeable functions or classes. My code looks something like this: from enum import Enum def foo(...): ... def bar(...): ... class Implementation(Enum): FOO = 1 BAR = 2 _IMPLEMENTATIONS = { Implementation.FOO: foo, Implementation.BAR: bar, } def call_implementation(implementation, *args, **kwargs): return _IMPLEMENTATIONS[implementation](*args, **kwargs) The first part of this blog post does a nice job of summarizing the general use case: http://lukasz.langa.pl/8/single-dispatch-generic-functions/ Obviously, enums are better than strings, because they're static declared and already grouped together. But it would be nice if we could do one better, by eliminating the dictionary, moving the dictionary values to the enum and making the enum instances. You might try this by writing a small subclass of Enum: class CallableEnum(Enum): def __call__(self, *args, **kwargs): return self.value(*args, **kwargs) class Implementation(CallableEnum): FOO = foo BAR = bar def call_implementation(implementation, *args, **kwargs): return implementation(*args, **kwargs) This looks great, with the Enum serving essentially as a typed namespace for a group of related functions, but unfortunately it this doesn't work. The problem is that when you assign a function to an Enum, it treats it as a method instead of an enum value: http://stackoverflow.com/questions/40338652/how-to-define-enum-values-that-are-functions Instead, you need to wrap function values in a callable class, e.g., from functools import partial class Implementation(CallableEnum): FOO = partial(foo) BAR = partial(bar) This is OK, but definitely uglier and more error prone than necessary. It's easy to forget to add a partial, which results in an accidental method declaration. It would be nice to have a CallableEnum class that works like Enum, but adds the __call_ method and doesn't allow defining any new methods: all functions assigned in the class body become Enum instances instead of methods. I would write this myself and throw it up on pypi, but there doesn't seem to be any way to do this short of delving into the guts of enum.EnumMeta <https://github.com/python/cpython/blob/0dc5c3169dcd4853612d11ed8c92b12fa210c07f/Lib/enum.py#L93>. Given that I think that others will also find this pattern useful, rather than forking the enum module I would like to add this into the standard library instead. Note: this proposal would also allow defining enum values using "def" inside the Enum body. But I think this is actually pretty clean, aside from general enum confusion over the fact that Implementation.FOO is Enum instance, not the method. class Implementation(CallableEnum): def FOO(...): ... def BAR(...): ...
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/