Search code examples
pythonpython-3.xerror-handlingpython-class

Function Chaining in Python, ignore rest of chain if a segment returns False


The title pretty much explains the problem. I don't know if there's a practical solution to this or if I'm being too picky over the behavior of my code. This article was hinting in the right direction, but I never got any code to work. https://medium.com/@adamshort/python-gems-5-silent-function-chaining-a6501b3ef07e

Here's an example of the functionality that I want:

class Calc:
    def __init__(self, n=0):
        self.n = n

    def add(self, n):
        self.n += n
        return self

    def might_return_false(self):
        return False

    def print(self):
        print(self.n)
        return self


w = Calc()

# The rest of the chain after might_return_false should be ignored
addedTwice = w.add(5).might_return_false().add(5).print()

w.print() # Should print 5

print(addedTwice) # Should print False

Solution

  • I think the article meant something more or less like below (but I prefer the other answer using exception, as it's more readable and better testable). Create a helper class:

    class Empty:
        def __call__(self, *args, **kwargs):
            return self
        def __getattr__(self, *args, **kwargs):
            return self
        def print(self, *args, **kwargs):
            return False
    

    and

    def might_return_false(self):
        return Empty()