None or 0

Tim Peters tim.one at comcast.net
Sat Sep 7 19:11:10 CEST 2002


[Michael Ströder]
> I'm using the idiom
>
> a = a or b
>
> to get rid of statements like
>
> if a is None:
>    a = b

That's fine, although you may get burned someday if 'a' has an interesting
value that's not None but happens to evaluate as false.  Like, e.g.,

    def eat(number_of_pounds=None):
        # Default to 1 pound.
        to_eat = number_of_pounds or 1
        ...

If you're not hungry and try to do eat(0), you're in for a treat.  As a rule
of thumb, whenever you use None to mean "not there", you'll cut bugs by
testing for "is None" or "is not None" explicitly.  I've seen many subtle
bugs as a result of not doing this; sometimes code works fine for years, and
then someone happens to add a __len__ method to an object's class, and "all
of a sudden" evaluating to false no longer means a var is still bound to
None, but that it may also be bound to a non-None object that suddenly
decided to call itself empty.

> Now I wonder what happens if both a and b have zero-length values.

If A evaluates to false, 'A or B' returns B without testing B (so it doesn't
matter whether B does or doesn't evaluate to false -- B is simply evaluated
and returned then).

> Trying in Python 2.2.1 reveals:
>
>  >>> repr(0 or None)
> 'None'
>  >>> repr(None or 0)
> '0'
>  >>> repr('' or None)
> 'None'
>  >>> repr(None or '')
> "''"
>  >>>
>
> Is it guaranteed to work like this

Yes.  Similarly, 'A and B' returns B untested whenever A evaluates to true.

   A or  B  same-as  if A then A else B
   A and B  same-as  if A then B else A

B is never tested for true/false, and in the cases where A is the result the
B expression isn't even evaluated.

> or should that be avoided?

That's really a different question <wink>.






More information about the Python-list mailing list