When you want to choose an algorithm from several options, you may want to associate a function with each value of an enumeration type.
In Java you can set a method for each value of an enum, but in Python you can't. Let's think about how to write it neatly in the direction of making Enum itself Callable.
Python Enums can be set freely. Therefore, the value itself should be a function.
However, the function defined in the class that inherits Enum is judged as a method and will not be included in the listed values.
class Dame(Enum):
#You're not defining a value, you're defining a method
A = lambda: print("A")
list(Dame)
#Empty list
So, I borrowed this stackoverflow idea and decided to use the tuple containing the function as the value.
from enum import Enum
class CallableEnum(Enum):
"""
Inherit this class to create a Callable Enum
"""
def __call__(self, *args,**kwargs):
return self.value[0](*args,**kwargs)
def register(func):
"""
Decorator to easily define tuples that contain functions
"""
return func,
Here's how to use it.
class Test(CallableEnum):
@register
def A():
print("A")
@register
def B():
print("B")
Test.A()
# A
Give the class T
that inherits Enum a dictionary from T
to the function, and refer to it in __call __
.
However, if "T
to function dictionary "is included as an attribute of T
in the class definition, it will also be one of the enumerated values. You have to add it after T
is completed as a class.
Therefore, it is a way to add a function after the class definition is finished.
from enum import Enum
class Dnum(Enum):
"""
Dispatching Enum. Inherit this guy
"""
@classmethod
def register(cls, key):
if not hasattr(cls, "table"):
cls.table = {}
def registration(func):
cls.table[key] = func
return registration
def __call__(self, *args,**kwargs):
return self.__class__.table[self](*args,**kwargs)
def register(enum):
def ret(func):
enum.__class__.register(enum)(func)
return ret
Use it like this.
from enum import auto
class Test(Dnum):
A = "A"
B = "B"
@register(Test.A)
def _A():
print("A")
@register(Test.B)
def _B():
print("B")
Test.A()
# A
Is there a trick to write a function in the class definition while setting the value freely?
Recommended Posts