Default __nonzero__ impl doesn't throw a TypeError exception

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Fri Jan 9 10:15:50 CET 2009


Bruno Desthuilliers a écrit :
> Sergey Kishchenko a écrit :
(snip)
>> #prints "Ouch!"
>> f=Foo()
>> if f:
>>     print "Ouch!"
>>
>> So, default __nonzero__ impl is to return True.
> 
> Yes. It's clearly documented FWIW.

To be more exact: there's no "default __nonzero__". The boolean value of 
an object is eval'd this way:

If the object is None (special cased by the interpreter AFAICT), it is 
false.
Else if the object implements __nonzero__, it has the boolean value 
returned by __nonzero__.
Else if the object implements __len__, it has the boolean value of its 
length.
Else if is true.

>> I think, this
>> behaviour conflicts with 'Explicit is better than implicit'
> 
> Why so ? It *is* explicit that the default for an object is to have a 
> true value in a boolean context.

I meant "explicit because documented", of course.


>> and
>> 'Practicality beats purity'
> 
> Quite on the contrary. From a practical POV, the default truth values of 
> Python objects are most of the time what you practically want in a 
> boolean context - that is, any non-None object, non-empty sequence and 
> non-zero numeric objects are true. __nonzero__ is here for the *very 
> few* corner cases where this is not the sensible default.


>> statements. I think, throwing a TypeError
>> exception would be better.  It will result in more explicit code with
>> fewer errors.


As a last note wrt/ explicitness and practicality: Implementing your 
proposition, one would have to either put each and every boolean 
expression in a try/except block or "explicitly" define __nonzero__ for 
each and any class - most of the time (about 99.9999% I'd say) 
implementing it as to return True - and expect that *everybody* does so.

So yes, from a "purity" POV, it might look "more explicit". But this 
would certainly not be practical at all.

OTHO, since boolean algebra only knows two values, it's clear that what 
is not false is by definition true. So having a default value (true) and 
a way to override it (__len__ and __nonzero__) is perhaps less "pure", 
but really as explicit and much more practical.

My 2 cents...



More information about the Python-list mailing list