I have an Enum instance method whose body consists of an if
statement with a condition for each of the Enum's members, like
class MyEnum(Enum):
INSTANCE_ONE = 1
INSTANCE_TWO = 2
def myInstanceMethod(self, arg1, arg2):
if self is MyEnum.INSTANCE_ONE:
# do some complicated stuff with the args over many lines of code
...
elif self is MyEnum.INSTANCE_TWO:
# do entirely different complicated stuff with the args
...
I would consider it more elegant if, instead, each of the Enum's members had its own implementation of myInstanceMethod
. But is there an elegant way to achieve that syntactically?
CodePudding user response:
One simple approach would be to use a decorator class to map the name of each enumerated value to the corresponding instance method by storing the mapping in a dict as a class attribute, so that when the wrapped method is called, the mapped function can be called based on the name of the Enum
instance:
class bind:
bound_methods = {}
def __init__(self, name):
self.name = name
def __call__(self, func):
def wrapper(wrapped_self, *args, **kwargs):
return self.bound_methods[(func.__qualname__, wrapped_self.name)](wrapped_self, *args, **kwargs)
self.bound_methods[(func.__qualname__, self.name)] = func
return wrapper
so that:
class MyEnum(Enum):
INSTANCE_ONE = 1
INSTANCE_TWO = 2
@bind('INSTANCE_ONE')
def myInstanceMethod(self, arg1, arg2):
return arg1 arg2
@bind('INSTANCE_TWO')
def myInstanceMethod(self, arg1, arg2):
return arg1 * arg2
print(MyEnum.INSTANCE_ONE.myInstanceMethod(2, 3))
print(MyEnum.INSTANCE_TWO.myInstanceMethod(2, 3))
would output:
5
6
Demo: https://replit.com/@blhsing/JuvenileFuzzyStrategy
CodePudding user response:
you could try to use lambda functions that are stored in each instance of the enum. It would look something like this:
class MyEnum(Enum):
INSTANCE_ONE = (1, lambda arg1, arg2 : print(arg1 arg2))
INSTANCE_TWO = (2, lambda arg1, arg2 : print(arg1 * arg2))
def myInstanceMethod(self, arg1, arg2):
self.value[1](arg1, arg2)
if you wanted something longer you could use the multi-line lambda like
lambda arg1, arg2 : (
line 1,
line 2,
line 3,
...
)
I hope this helped but if you want to keep the code somewhere else you could also do it by creating global methods and just calling those in your lambda functions