[Python-ideas] Method chaining notation

Steven D'Aprano steve at pearwood.info
Sat Feb 22 02:13:09 CET 2014


On Sat, Feb 22, 2014 at 04:30:03AM +1100, Chris Angelico wrote:
> Yeah, I'm insane, opening another theory while I'm busily championing
> a PEP.

Completely raving bonkers :-)

> In Python, as in most languages, method chaining requires the method
> to return its own object.
[...]

Rather than add syntactic support for this, I'd prefer a wrapper in the 
standard library. Syntax implies to me that chaining operators is, in 
some sense, a preferred idiom of the language, and although method 
chaining is sometimes useful, I don't think that it ought to be 
preferred. There's a difference between "Python supports this, use this 
syntax" and "You can do this in Python, import this library and call 
this function to make it happen".


[...]
> So here's the proposal. Introduce a new operator to Python, just like
> the dot operator but behaving differently when it returns a bound
> method. We can possibly use ->, or maybe create a new operator that
> currently makes no sense, like .. or .> or something. Its semantics
> would be:
> 
> 1) Look up the attribute following it on the object, exactly as per
> the current . operator
> 2) If the result is not a function, return it, exactly as per current.
> 3) If it is a function, though, return a wrapper which, when called,
> calls the inner function and then returns self.

When you say "a function", do you actually mean a function? What about 
other callables, such as methods (instance, class or static) or types? 
How does this interact with the descriptor protocol?


> This can be done with an external wrapper, so it might be possible to
> do this with MacroPy. It absolutely must be a compact notation,
> though.

Here's an alternative: add a `chained` wrapper to, oh, let's say 
functools (I don't think it needs to be a built-in). In my hierarchy of 
language preferredness, this suggests that while Python *supports* 
method chaining, it isn't *preferred*. (If it were preferred, it would 
happen by default, or there would be syntax for it.) If you want to 
chain methods, you can, but it's a slightly unusual thing to do, and the 
fact that you have to import a module and call a wrapper class should be 
sufficient discouragement for casual (ab)use.

Inspired by the Ruby "tap" method, I wrote this proof-of-concept last 
year:

https://mail.python.org/pipermail/python-list/2013-November/660892.html

http://code.activestate.com/recipes/578770-method-chaining/

Of course, if the class author wants to support method chaining, they 
can always write the methods to return self :-)


-- 
Steven


More information about the Python-ideas mailing list