Reputation: 171
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?
Upvotes: 2
Views: 2025
Reputation: 106648
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
Upvotes: 4
Reputation: 39
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
Upvotes: 1