Method chaining

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Nov 24 09:27:42 EST 2013


On Sat, 23 Nov 2013 19:53:32 +0000, Rotwang wrote:

> On 22/11/2013 11:26, Steven D'Aprano wrote:
>> A frequently missed feature is the ability to chain method calls:
[...]
>> chained([]).append(1).append(2).append(3).reverse().append(4) =>
>> returns [3, 2, 1, 4]
> 
> That's pretty cool. However, I can imagine it would be nice for the
> chained object to still be an instance of its original type.

Why? During the chained call, you're only working with the object's own 
methods, so that shouldn't matter. Even if a method calls an external 
function with self as an argument, and the external function insists on 
the original type, that doesn't matter because the method sees only the 
original (wrapped) object, not the chained object itself.

In other words, in the example above, each of the calls to list.append 
etc. see only the original list, not the chained object.

The only time you might care about getting the unchained object is at the 
end of the chain. This is where Ruby has an advantage, the base class of 
everything has a method useful for chaining methods, Object.tap, where in 
Python you either keep working with the chained() wrapper object, or you 
can extract the original and discard the wrapper.


> How about something like this:
> 
> def getr(self, name):
>      obj = super(type(self), self).__getattribute__(name) 

I don't believe you can call super like that. I believe it breaks when 
you subclass the subclass.


-- 
Steven



More information about the Python-list mailing list