[Tutor] Tips

Steven D'Aprano steve at pearwood.info
Thu Jun 19 03:17:14 CEST 2014


On Wed, Jun 18, 2014 at 07:25:41AM -0700, Albert-Jan Roskam wrote:

> Given that the concept of Ducktyping has already been mentioned, is 
> there a reason why you did not mention try-except?
>  
> def add(a, b):
>     try:
>         return a + b
>     except TypeError:
>         raise 

As others have mentioned, this is pointless -- there is no good reason 
to catch an exception, only to *unconditionally* re-raise it.

Sometimes it is useful to conditionally re-raise:

try:
    something()
except SomeFailure as e:
    if e.condition == foo:
        raise
    else:
        do_something_else()

but even that is pretty rare. In general, the rule is to never catch any 
exception you aren't prepared to deal with in some way.

 
> Btw, given that:
> >>> {}.__add__ 
> Traceback (most recent call last): 
> File "", line 1, in AttributeError: 
> 'dict' object has no attribute '__add__'
>
> Why does one only need to use 'except TypeError', not 'except 
> (TypeError, AttributeError)' in the try-except above?

You answer your own question by trying it:

> >>> {} + 1 
> Traceback (most recent call last): 
> File "", line 1, in TypeError: 
> unsupported operand type(s) for +: 'dict' and 'int'


You don't need to worry about AttributeError for __add__ because you 
aren't calling __add__ directly, you're using the + operator.

x + y is not the same as calling x.__add__(y). It's actually quite 
clever, it gives *both* x and y a chance to decide what to do:

(1) if y is a subclass of x, then try calling y.__radd__(x)
    otherwise try calling x.__add__(y)
(2) if the method doesn't exist (raises AttributeError), 
    or it returns the special value NotImplemented,
    try the other way around, x.__add__(y) or y.__radd__(x)
(3) if that method also doesn't exist, or returns 
    NotImplemented, then raise TypeError

So you can see, the + operator catches the AttributeError raised if the 
object doesn't have __add__ or __radd__ methods, either to try a 
different method, or to turn it into a TypeError.



-- 
Steven


More information about the Tutor mailing list