Reputation: 597
So I saw this code somewhere.
1] So why are we returning self at the end of each method?what purpose does it serve?
2] How to interpret the method chaining (last line)- doug.set_legs(4).count_legs().sleep().sleep().sleep()
class pet:
number_of_legs = 0
def sleep(self):
print "zzz "
return self
def set_Legs(self, legs):
self.number_of_legs = legs
return self
def count_legs(self):
print "I have %s legs" % self.number_of_legs
return self
class dog(pet):
def bark(self):
print "Woof"
doug = dog()
doug.set_Legs(4).count_legs().sleep().sleep().sleep() # Any explanation for this chaining & how its operating particularly in this case ??
>>>I have 4 legs
ZZZ
ZZZ
ZZZ
Out[249]: <__main__.dog instance at 0x7fd5d81917e8> # Why & from where this part getting printed ??
doug.set_legs(4).count_legs().sleep().set_legs(10).count_legs().sleep().sleep()
>>>I have 4 legs
ZZZ
I have 10 legs
ZZZ
ZZZ
Out[242]: <__main__.dog instance at 0x7fd5d81917e8> # Why & from where this part getting printed ??
Upvotes: 0
Views: 126
Reputation: 2067
This is an example of the Method Chaining pattern. While it's unusual in Python, it can generally be useful if you want to perform multiple actions on the same object. Because of this, it's most often seen in jQuery programming, e.g. for modifying elements on a webpage.
Since the sleep
, set_legs
and count_legs
methods don't return anything of importance, you could just as well return the object the method was called on instead of not returning anything.
By this, if you want to do something else on the same object right after, you can compress it into one line of code.
To explain your line of code:
doug # the Dog object
.set_Legs(4) # call set_legs on doug, returning doug
.count_legs() # call count_legs on doug, returning doug
.sleep() # call sleep on doug, returning doug
.sleep() # call sleep on doug, returning doug
.sleep() # call sleep on doug, returning doug
The last printed line is your python interpreter showing the return value of the function, i.e. doug
. You could call even more set_legs
, count_legs
, etc. on that.
The above code is equivalent to doing:
doug.set_Legs(4)
doug.count_legs()
doug.sleep()
doug.sleep()
doug.sleep()
Upvotes: 2
Reputation: 99
1)
def sleep(self):
print "zzz "
return self
Your methods can return anything. The only obligation, for a method in a class, is to have 'self' as the first parameter. That's all. You have no reason to return the object. Some of your functions do not need any return statement!
def sleep(self):
print "zzz "
2) Interpret it in the way it's written: from left to right. Those previous returns were there for you to be able to chain this way (you chain on the return value).
Upvotes: 0
Reputation: 282026
Returning self
is useful for method chaining, so you can do
doug.set_Legs(4).count_legs().sleep().sleep().sleep()
instead of
doug.set_Legs(4)
doug.count_legs()
doug.sleep()
doug.sleep()
doug.sleep()
This doesn't look like a very appropriate place to apply it. It can be useful when you want to apply a sequence of transformations to an object, like in jQuery.
As for the method chaining,
doug.set_Legs(4).count_legs().sleep().sleep().sleep()
is equivalent to
temp = doug.set_Legs(4)
temp = temp.count_legs()
temp = temp.sleep()
temp = temp.sleep()
temp = temp.sleep()
which, since all the methods here return self
, is equivalent to
doug.set_Legs(4)
doug.count_legs()
doug.sleep()
doug.sleep()
doug.sleep()
Upvotes: 1
Reputation: 32720
Both questions are related. The methods return self which is the object you are working on and this allows you to chain methods as the result of the first method is the object you call the second method on.
e.g.
doug = dog()
doug.set_Legs(4).count_legs().sleep()
is equivalent to
doug = dog()
doug.set_Legs(4)
doug.count_legs()
doug.sleep()
Upvotes: 2