[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