0

Is a try except clause discouraged in Python if it can be avoided and is part of a normally functioning piece of code? For example, in the following two code snippets, which is preferred?

Option 1:

try:
    id = list.index(42)
except:
    print("42 not found")
else:
    print("ID: ", id)

Option 2:

if 42 in list:
    id = list.index(42)
    print("ID: ", id)
else:
    print("42 not found")
Matthew D. Scholefield
  • 2,977
  • 3
  • 31
  • 42
  • 3
    No, they are not. A recommended design principle in python is EAFP, instead of LBYL, see [Python Glossary](https://docs.python.org/2/glossary.html) – AChampion Mar 10 '16 at 02:06
  • FYI: `EAFP:` Easier to Ask for Forgiveness than Permission, and `LBYL:` Look Before You Leap – Selcuk Mar 10 '16 at 02:07
  • 3
    Well, actually there could be many more issues with a program other than simple checks. in fact try/catch are encouraged and are considered good practice. – Saleem Mar 10 '16 at 02:08
  • 3
    And on the topic of good Python style - don't name variables after standard type names, as tempting as this might be. So no lists named "list", dicts named "dict", tuples named "tuple", or strings named "str". – PaulMcG Mar 10 '16 at 02:10
  • @PaulMcGuire you shouldn't even name strings `list`, dicts `str`, or lists `dict` :P – MattDMo Mar 10 '16 at 02:13
  • Trying it is the best way to find out if something will work. `list.index()` is more likely to know what is valid than you are. – zondo Mar 10 '16 at 02:14

2 Answers2

2

They are not discouraged.

However, your example is silly because you do not need an exception and you could for example accidentally have typos in your list.index code, which would trigger your exception, and you would never know.

Use exceptions and catch them if you know what exception you are catching -- and it's not trivial to do a "look before you leap" check (like it is in your example). Often that won't be the case. However, in your example it is.

Oh, and try to avoid a blanket except: catch (especially if you know how you expect your try to fail). That can easily enable bad practice since you pretty much by definition have no idea what your call might do/raise. If your application requires this (such as the server example pointed out by Paul in comments) that is fine, but if you are trying to lookup a value in a list? That's... not good.

As a good example of why this isn't good combined for your example:

try:
    id = list.idex(42)
except:
    print("42 not found")
else:
    print("ID: ", id)
enderland
  • 13,825
  • 17
  • 98
  • 152
  • 1
    I disagree. `except Exception:` is nothing to be avoided, and is often used in server apps to avoid crashing a long-running service because of badly behaved code. The case to avoid is the bare `except:`, and even worse `except: pass`, which *does* grab all exceptions, and then merrily trudges on. The killer is that `except:` also catches exceptions you normally want to let thru, like KeyboardInterrupt (when hitting ^C) or SysExit - `except: pass` in a while-True-loop will make for a difficult program to kill. – PaulMcG Mar 10 '16 at 02:21
  • 1
    @PaulMcGuire I clarified to address that - I mistakenly put `Exception:` instead of `except:` when I wrote this the first time... – enderland Mar 10 '16 at 02:25
0

All depends on your needs:

If you have a significant dependence on the performance, try-except clauses are discouraged.

Otherwise you can use try-except clauses as a clear pattern.

Anyway, in your example I think the if-else code clearer than the try-except one.