Search code examples
pythonmethod-chaining

method chaining in python


(not to be confused with itertools.chain)

I was reading the following: http://en.wikipedia.org/wiki/Method_chaining

My question is: what is the best way to implement method chaining in python?

Here is my attempt:

class chain():
    def __init__(self, my_object):
        self.o = my_object

    def __getattr__(self, attr):
        x = getattr(self.o, attr)
        if hasattr(x, '__call__'):
            method = x
            return lambda *args: self if method(*args) is None else method(*args)
        else:
            prop = x
            return prop

list_ = chain([1, 2, 3, 0])
print list_.extend([9, 5]).sort().reverse()

"""
C:\Python27\python.exe C:/Users/Robert/PycharmProjects/contests/sof.py
[9, 5, 3, 2, 1, 0]
"""

One problem is if calling method(*args) modifies self.o but doesn't return None. (then should I return self or return what method(*args) returns).

Does anyone have better ways of implementing chaining? There are probably many ways to do it.

Should I just assume a method always returns None so I may always return self.o ?


Solution

  • Caveat: This only works on class methods() that do not intend to return any data.

    I was looking for something similar for chaining Class functions and found no good answer, so here is what I did and thought was a very simple way of chaining: Simply return the self object.

    So here is my setup:

    class Car:
        def __init__(self, name=None):
            self.name = name
            self.mode = 'init'
    
        def set_name(self, name):
            self.name = name
            return self
    
        def drive(self):
            self.mode = 'drive'
            return self
    

    And now I can name the car and put it in drive state by calling:

    my_car = Car()
    my_car.set_name('Porche').drive()
    

    Hope this helps!