I couldn't find anything on this subject on Google, so I think I should ask it here:
Is it possible to chain functions with Python, like jQuery does?
['my', 'list'].foo1(arg1, arg2).foo2(arg1, arg2).foo3(arg1, arg2) #etc...
I am losing a lot of space and readability when I write this code:
foo3(foo2(foo1(['my', 'list'], arg1, arg2), arg1, arg2), arg1, arg2) #etc...
There seems to exist some illusive library for creating such functions, but I can't seem to see why this has to be so complicated-looking...
Thanks!
With jQuery, you can chain together actions/methods. Chaining allows us to run multiple jQuery methods (on the same element) within a single statement.
Method chaining is a programmatic style of invoking multiple method calls sequentially with each call performing an action on the same object and returning it. It eliminates the cognitive burden of naming variables at each intermediate step.
jQuery | chaining() With jQuery, we can use do chaining which means to chain together multiple methods in a single statement on a single element.
As long as the function returns a value, you can chain it. In jQuery, a selector method usually returns the selector itself, which is what allows you to do the chaining. If you want to implement chaining in python, you could do something like this:
class RoboPuppy:
def bark(self):
print "Yip!"
return self
def growl(self):
print "Grr!"
return self
pup = RoboPuppy()
pup.bark().growl().bark() # Yip! Grr! Yip!
Your problem, however, seems to be that your function arguments are too cramped. Chaining is not a solution to this. If you want to condense your function arguments, just assign the arguments to variables before passing them to the function, like this:
spam = foo(arg1, arg2)
eggs = bar(spam, arg1, arg2)
ham = foobar(eggs, args)
Here's an expansion of Simon's ListMutator
suggestion:
class ListMutator(object):
def __init__(self, seq):
self.data = seq
def foo1(self, arg1, arg2):
self.data = [x + arg1 for x in self.data]
# This allows chaining:
return self
def foo2(self, arg1, arg2):
self.data = [x*arg1 for x in self.data]
return self
if __name__ == "__main__":
lm = ListMutator([1,2,3,4])
lm.foo1(2, 0).foo2(10, 0)
print lm.data
# Or, if you really must:
print ListMutator([1,2,3,4]).foo1(2, 0).foo2(10, 0).data
You could go one better and make ListMutator
act entirely like a list by using the collections abstract base classes. In fact, you could subclass list
itself, although it may restrict you from doing certain things you might need to do... and I don't know what the general opinion is on subclassing built-in types like list
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With