[Tutor] Tips
Albert-Jan Roskam
fomcl at yahoo.com
Thu Jun 19 09:22:09 CEST 2014
----- Original Message -----
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Cc:
> Sent: Thursday, June 19, 2014 3:17 AM
> Subject: Re: [Tutor] Tips
>
> 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.
Aha!!! I always thought that "+" was perfectly equivalent to "__add__", just a more readable way of writing this (I would almost use the term "syntactical sugar" but for some reason that only seems to be used in the context of decorators, so I don't. Oops, I still did use that term. Oh well :-)
> 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.
Now I understand it. Very interesting. Thanks, that was exactly what I meant! "+" != "__add__".
More information about the Tutor
mailing list