2

I am trying to write a Python class that will allow me to use it in code like this:

mc = MyClass()
mc.foo()
  .bar()

I have written the class like this:

class MyClass(object):
    def __init__(self):
        pass
    def foo(self):
        print "foo called"
        return self
    def bar(self):
        print "bar called"
        return self

However, the only way I can get close to the "beautiful" style I want, is to introduce backslashes like so (run in both IPython and IDLE):

>>> mc = MyClass()
>>> mc.foo()\
       .bar()

Is there any way I can do without the backslashes?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
  • Never thought about it by to my understanding this is not possible. Each tab and new line is a new execution in Python. Unless backslashes are used. So my answer would be, no. – Torxed May 05 '15 at 13:00
  • You can put the whole thing in parentheses, but that probably doesn't make it any prettier. – interjay May 05 '15 at 13:01
  • 1
    No, you can't do that. Why would you want to? *Explicit is better than implicit* (`import this`). – jonrsharpe May 05 '15 at 13:01
  • 1
    I just tested this in spider, and I agree, since `mc.foo().bar()` is the command and `.bar()` is not an entire command on its own – Matthew May 05 '15 at 13:01
  • @jonrsharpe This is not about implicit vs. explicit. If `mc.foo().bar()` is okay, then a couple of newline characters shouldn't suddenly mean we are violating pythonic guidelines. See http://martinfowler.com/bliki/FluentInterface.html for more on why this approach can be nice in certain situations. – Seth Dec 02 '16 at 05:40
  • Possible duplicate of [How to break a line of chained methods in Python?](http://stackoverflow.com/questions/4768941/how-to-break-a-line-of-chained-methods-in-python) – Seth Dec 02 '16 at 05:43

3 Answers3

1

No. Python is layout-dependent, and newlines (unless enclosed in brackets or escaped using a backslash) terminate a statement. As far as I'm aware, there is no way to bend it to accept this syntax.

What makes you want to do that? Personally, I would argue against it based on readability. Both the alternatives below seem clearer to me, and I'd prefer the latter (when method names are sufficiently short and simple).

mc = MyClass()
x = mc.foo()
x.bar()

mc = MyClass()
mc.foo().bar()

As, in this case, you know the result of foo() is of type MyClass, you might even just call it as follows. When possible, this is definitely the preferable method (and you can omit the return statements altogether).

mc = MyClass()
mc.foo()
mc.bar()
Joost
  • 4,094
  • 3
  • 27
  • 58
  • Or even just `mc.foo(); mc.bar()`; there's no need for the methods to `return self`. – jonrsharpe May 05 '15 at 13:10
  • @jonrsharpe note that while that would work for this example, as `self` is returned, it is not a general translation from `mc.foo().bar()`. Good call though, I added an example. – Joost May 05 '15 at 13:12
1

You can enclose your command in parenthesis. Python, does not "finishes" a command while there is a open parenthesis. It is not perfect, but useful if you chain a lot of commands:

mc = MyClass()
(mc.foo()
   .bar())
neves
  • 33,186
  • 27
  • 159
  • 192
0

I recently invoked a fluent interface, like this:

mc = MyClass()
mc.foo(
 ).bar(
 )

Assuming foo and bar have parameters, which they did in my case, you can dedicate a line (or more) to the parameters of each function:

mc = MyClass()
mc.foo(foo_par1, foo_par2, foo_par3
 ).bar(bar_par1, bar_par2
 )
David Wallace
  • 212
  • 4
  • 12