[Python-Dev] Returning None from methods that mutate object state

Steven D'Aprano steve at pearwood.info
Sat May 17 12:44:35 CEST 2014


On Sat, May 17, 2014 at 04:26:12AM -0400, Terry Reedy wrote:
> On 5/17/2014 1:14 AM, Nick Coghlan wrote:
> >During a conversation today, I realised that the convention of
> >returning None from methods that change an object's state isn't
> >captured the Programming Recommendations section of PEP 8.
> >Specifically, I'm referring to this behaviour:
> >
> >>>>[].sort() is None
> >True
> >>>>"ABC".lower() is None
> >False
> 
> When list.pop was added, the convention was changed to
> "do not return the 'self' parameter"

I don't think "return self" was ever the convention. Here's Python 1.5:

[steve at ando ~]$ python1.5
Python 1.5.2 (#1, Aug 27 2012, 09:09:18)  [GCC 4.1.2 20080704 (Red Hat 
4.1.2-52)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> [].sort() is None
1
>>> [].reverse() is None
1
>>> [1, 2, 3].remove(2) is None
1
>>> {}.update({}) is None
1

(Wow. Returning 1 instead of True -- it's ages since I've seen that.)

I think the rule "return None, not self" should be best understood as 
applying only to mutator methods which *only* operate for their 
side-effects (like sorting, reversing), not those which also have an 
obvious return value:

>>> [2, 4, 6].pop()  # Still Python 1.5.
6

I don't recall any other examples from 1.5 that did this.


> it.__next__ is another mutator that returns neither self or None.
> 
> Actually, if one regards file read and write as mutation, then returning 
> None never was the rule.

I don't think we should regard reading as a mutation :-) 

Writing to a file on disk may be a side-effect, but I don't think it 
counts as a mutation of the file object. But even if we consider it as 
one, prior to 3.x writing returned None. This is from 2.7:

py> open("/dev/null", "w").write("goodbye cruel world") is None
True


> It seems to me that the actual Python rule is "Don't return 'self'. If 
> there is nothing useful to return (other than self), return None." I 
> believe this is true whether or not self is mutated. (Of course, there 
> might be an exception I have overlooked.)

The obvious exception is the iterator protocol: __iter__ of an iterator 
must return self. But that's an exceptional case.

I don't think it is fair to say that Python imposes a *rule* "don't 
return self" -- it's more of a convention for built-ins only, not a rule 
for all Python classes. Ruby prefers methods that return self and are 
therefore chainable, while Python built-ins do not.

I think it would be worth having PEP 8 make it clear that:

- built-ins, and types which share the same interface as built-ins, 
  should have mutators which return None rather than self;

- but third-party types (including classes in the standard library, if 
  necessary) may return self;

- whichever choice you make, be consistant within a single API. E.g. 
  don't have x.mutator1() return None, while x.mutator2() returns self.


-- 
Steven


More information about the Python-Dev mailing list