Home > OS >  Chain class methods with condition
Chain class methods with condition

Time:07-08

Imagine I have the following simplified class:

class ExampleClass:
    def __init__(self, input_1):
        self.input_1 = input_1

    def method_1(self):
        # Do something
        return self

    def method_2(self):
        # Do something
        return self

    def method_3(self):
        # Do something
        return self

instance = ExampleClass('Hello')

If I wanted to call the methods sequentially, I could simply chain them as such:

instance \
    .method_1() \
    .method_2() \
    .method_3()

Now imagine I also have a condition, that if evaluates to true, should call method_2(), otherwise call method_3(). I can achieve this by writing:

dummy_condition = True

instance.method_1()

if dummy_condition:
    instance.method_2()
else:
    instance.method_3()

Question: How can I perform this logic without so much verbose code, using method chaining instead? I have tried being creative, and came up with the following, which unfortunately doesn't work:

instance \
    .method_1() \
    (.method_2() if dummy_condition else .method_3())

Any ideas?

CodePudding user response:

You can do something like this instead:

instance.method_1().__getattribute__("method_2" if dummy_condition else "method_3")()

This utilises __getattribute__ dunder then calls it

CodePudding user response:

You should use the __getattribute__ magic method. You are able to get an attribute of your instance based on name (str) of its.

__getattribute__:

Called unconditionally to implement attribute accesses for instances of the class. If the class also defines getattr(), the latter will not be called unless getattribute() either calls it explicitly or raises an AttributeError. This method should return the (computed) attribute value or raise an AttributeError exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.getattribute(self, name).

Reference:

Code:

class ExampleClass:
    def __init__(self, input_1):
        self.input_1 = input_1

    def method_1(self):
        print("METHOD_1")
        return self

    def method_2(self):
        print("METHOD_2")
        return self

    def method_3(self):
        print("METHOD_3")
        return self


instance = ExampleClass("Hello")

dummy_condition = True

instance.method_1().__getattribute__("method_2" if dummy_condition else "method_3")()

Output:

>>> python3 test.py 
METHOD_1
METHOD_2

Output if dummy_condition = False:

>>> python3 test.py 
METHOD_1
METHOD_3
  • Related