Boolean tests [was Re: Attack a sacred Python Cow]

Matthew Fitzgibbons elessar at nienna.org
Thu Jul 31 15:07:59 EDT 2008


Matthew Fitzgibbons wrote:
> Steven D'Aprano wrote:
>> On Wed, 30 Jul 2008 09:23:05 -0600, Matthew Fitzgibbons wrote:
>>
>>> If you're expecting a list (and only a list)
>>> then your point makes sense. 'if x' can get you into trouble if you
>>> _don't_ want its polymorphism.
>>
>> "if x" is hardly unique in that way. If you're expecting a list, and 
>> only a list, "len(x) != 0" will get you in trouble if somebody passes 
>> a string or a dictionary. I don't see any reason why we should single 
>> out "if x" as dangerous in the face of invalid types. With the 
>> exception of the "is" and "is not" operators, nothing in Python is 
>> guaranteed to work with any imaginable object. Even print can fail, if 
>> the object's __str__ method raises an exception.
>>
>>  
>>> Although, if my function is expecting a list, my preference is to do:
>>>
>>> if not isinstance(x, list):
>>>      raise SomeMeaningfulException()
>>> # do stuff with the list
>>>
>>> I put my type checking at the top of the function, so readers can
>>> reference it easily.
>>
>> And thus you break duck-typing and upset anybody who wants to pass a 
>> sequence that doesn't inherit directly from list.
>>
>> There are other (and arguably better, although more labour-intensive) 
>> techniques for defensive programming that don't break duck-typing. You 
>> can google for Look Before You Leap and Easier To Ask Forgiveness Than 
>> Permission for more information. Alex Martelli has a fine recipe in 
>> the Python Cookbook -- search for the recipe "Checking if an object 
>> has the necessary attributes".
>>
>> But in a nutshell, here's a toy example:
>>
>> def spam(seq):
>>     try:
>>         seq.append
>>         seq.extend
>>         seq[0] = seq[0]
>>     except Exception:
>>         raise TypeError("argument isn't sufficiently sequence-like")
>>     # No exceptions expected from here on
>>     seq.append(seq[0])
>>     seq.extend([1,2,3])
>>     seq[0] = "spam"
>>
>>
>>
>>
> 
> Yes, I know it breaks duck typing, which is why I do it only very 
> rarely, and never with e.g. sequence types. If I use ifinstance for type 
> checking, it's because I need some _very_ specific class, almost always 
> one that I wrote. My more usual use case for ifinstance is to figure out 
> how to handle a particular object using introspection.
> 
> That said, your example is still helpful. It's a good approach, and I 
> should use it more often. Although I'd also lean toward hasattr and 
> iscallable and ordinary ifs instead of the try ... except where 
> possible. Depending on what you put in the try ... except, you risk 
> masking legit exceptions.
> 
> Ahhh, Programing. Where no rule of thumb seems to last five minutes.
> 
> -Matt
> -- 
> http://mail.python.org/mailman/listinfo/python-list
> 

Where by ifinstance I mean isinstance and by iscallable I mean callable.

*hides*

-Matt



More information about the Python-list mailing list