----- Original Message -----
> From: Steven D'Aprano <st...@pearwood.info> > To: tutor@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__". _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor