Home > database >  In Python, how do I give each member of an Enum its own implementation of an Enum instance method?
In Python, how do I give each member of an Enum its own implementation of an Enum instance method?

Time:07-26

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

  • Related