Boolean tests [was Re: Attack a sacred Python Cow]
modelnine at modelnine.org
Tue Jul 29 21:43:02 CEST 2008
Am 29.07.2008, 18:30 Uhr, schrieb Carl Banks <pavlovevidence at gmail.com>:
> On Jul 29, 5:15 am, Heiko Wundram <modeln... at modelnine.org> wrote:
>> I can't dig up a simple example from code I wrote quickly, but because
>> of the
>> fact that explicit comparisons always hamper polymorphism
> I'm not going to take your word for it. Do you have code that
> demonstrates how "if x" improves polymorphism relative to simple
> explicit tests?
As I wrote in the second reply email I sent, check out my integer set
recipe on ASPN (and to save you the search:
http://code.activestate.com/recipes/466286/). To test whether the integer
set is empty or not (in a polymorphic function which accepts any kind of
sequence type), the explicit test would be, as you proposed elsewhere:
len(x) > 0. This simply WILL NOT work with some sets of that respective
type, because, as I documented for the __len__() method there: the return
value of __len__() has to (had to?) be in the range 0 <= len < 2**31
(which I think means, as I tested and implemented it on i386, that the
return value has to fit in an ssize_t platform type, but someone with more
knowledge of the interpreter internals might be able to comment here; I'm
not in the mood for checking this out now).
Another reason why the test for __nonzero__() is beneficial, at least
here: testing whether the set is empty or not is easy, because an empty
set has no ranges, and a set with at least one element has at least one
range (i.e., to test whether the set is non-empty, check whether the
_ranges member, a list, is __nonzero__()); taking the len() of a set
always means adding the size of the ranges together (even though this
could of course be precomputed/cached, as the set type is immutable, but
I'm not doing that in that recipe's code).
So, adding things up: the interpretation of __nonzero__(), i.e. the direct
"conversion" to bool, for container-types, implements THE means to test
whether the container is empty or not. Insisting on not using it, because
a "simple explicit" test is supposedly better, will prove to not work in
those cases where the container type might not have a representable length
(because of the constraints on the return value of __len__()), even though
the container has an empty/non-empty state.
I think this does make a very compelling use case for "if x" instead of
"if len(x) > 0".
More information about the Python-list