How do I chain methods?

C

chad

I tried the following...



#!/usr/bin/python

class foo:
def first(self):
print "Chad "

def last(self):
print "A "

x = foo()
y = x.first()
y.last()

But when I ran it, I got the following...

[cdalten@localhost oakland]$ ./chain.py
Chad
Traceback (most recent call last):
File "./chain.py", line 12, in ?
y.last()
AttributeError: 'NoneType' object has no attribute 'last'
[cdalten@localhost oakland]$
 
C

Chris Rebert

How do I chain methods?
I tried the following...

#!/usr/bin/python

class foo:
   def first(self):
       print "Chad "

   def last(self):
       print "A "

x = foo()
y = x.first()
y.last()

But when I ran it, I got the following...

[cdalten@localhost oakland]$ ./chain.py
Chad
Traceback (most recent call last):
 File "./chain.py", line 12, in ?
   y.last()
AttributeError: 'NoneType' object has no attribute 'last'
[cdalten@localhost oakland]$

Functions/methods without "return" statements, such as your last() and
first(), implicitly return None, Python's equivalent of null. Python
has no special support for method chaining; having your methods
`return self` achieves the same effect however.

Method chaining is usually* not idiomatic in Python. Most people would
instead just write:
x = foo()
x.first()
x.last()

If you insist on method chaining, adding the aforementioned `return`
statements would let you write:
x = foo()
x.first().last()

Cheers,
Chris
 
J

James Mills

I tried the following...



#!/usr/bin/python

class foo:
   def first(self):
       print "Chad "

   def last(self):
       print "A "

x = foo()
y = x.first()
y.last()

But when I ran it, I got the following...

[cdalten@localhost oakland]$ ./chain.py
Chad
Traceback (most recent call last):
 File "./chain.py", line 12, in ?
   y.last()
AttributeError: 'NoneType' object has no attribute 'last'
[cdalten@localhost oakland]$

What you want is this:
.... def first(self):
.... print "Chad "
.... return self
.... def last(self):
.... print "A "
.... return self
....

NB: You must return "self" in this case so you can do chained calls.

cheers
James
 
J

James Mills

Method chaining is usually* not idiomatic in Python.

I don't agree but anyway... I've just not seen it commonly used
amongst python programmers.

cheers
James
 
C

chad

I don't agree but anyway... I've just not seen it commonly used
amongst python programmers.

cheers
James

I just saw this technique used in python script that was/is used to
automatically log them in myspace.com. Hence the question.
 
J

James Mills

I just saw this technique used in python script that was/is used to
automatically log them in myspace.com. Hence the question.

Function/Method Chaining is probably used a lot in Python itself:
2

The implementation of many common operators return self (the object
you're working with).

cheers
James
 
S

Steve Holden

Function/Method Chaining is probably used a lot in Python itself:

2

The implementation of many common operators return self (the object
you're working with).
You surely aren't trying to suggest that (4).__add__(1) returns 4?

regards
Steve
 
S

Steven D'Aprano

Function/Method Chaining is probably used a lot in Python itself:

2

The implementation of many common operators return self (the object
you're working with).


I can't think of any operations on built-ins that return self, except in
the special case of an identity operation. And even then, it's not common:
False


Ah wait, no, I thought of one: __iadd__:
x = [2.5]
y = x.__iadd__([None])
y is x
True

But:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'float' object has no attribute '__iadd__'



By the way, in case any newbies out there are reading...

....if you're writing x.__add__(1).__sub__(3) instead of x + 1 - 3 then
you're almost certainly doing it wrong.
 
J

James Mills

...if you're writing x.__add__(1).__sub__(3) instead of x + 1 - 3 then
you're almost certainly doing it wrong.

It was just an example :) ... And this isn't python-tutor

--James
 
J

James Mills

Function/Method Chaining is probably used a lot in Python itself:

2

The implementation of many common operators return self (the object
you're working with).

My apologies, this was a terribly example! int is immutable and
__add__ nor __sub__ return self :)

cheers
James
 
C

Chris Rebert

I don't agree but anyway... I've just not seen it commonly used
amongst python programmers.

If Python wanted to encourage method-chaining-style, then list.sort(),
list.reverse(), and several other built-in type methods would (ala
Ruby) return self rather than None. Since they don't, and since
"uncommon idiom" is a near-oxymoron, I think we can safely conclude
that method chaining isn't idiomatic in Python. Not that it doesn't
have specialized uses though (See asterisk note).

Cheers,
Chris
 
S

Steve Holden

If Python wanted to encourage method-chaining-style, then list.sort(),
list.reverse(), and several other built-in type methods would (ala
Ruby) return self rather than None. Since they don't, and since
"uncommon idiom" is a near-oxymoron, I think we can safely conclude
that method chaining isn't idiomatic in Python. Not that it doesn't
have specialized uses though (See asterisk note).
Yes, the Twisted guys use method chaining a lot - it's definitely
idiomatic in that framework.

regards
Steve
 
T

Terry Reedy

If Python wanted to encourage method-chaining-style, then list.sort(),
list.reverse(), and several other built-in type methods would (ala
Ruby) return self rather than None. Since they don't, and since
"uncommon idiom" is a near-oxymoron, I think we can safely conclude
that method chaining isn't idiomatic in Python.

It is intentionally not idiomatic for methods that mutate or otherwise
operate strictly by side-effect, as in the OP example.

It *is* idiomatic for methods that return new objects.
'Abc Def'

And, of course, it is used internally to implement expressions with
operators that also produce new objects.
True
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top