[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