try/except KeyError vs "if name in ..."

Günther Dietrich gd.usenet at spamfence.net
Sat Oct 6 04:49:55 EDT 2012


Manuel Pégourié-Gonnard <mpg at elzevir.fr> wrote:

>Hi,
>I was looking at the example found here [1] which begins with:
>
>[1] http://docs.python.org/py3k/library/imp.html#examples
>
>def __import__(name, globals=None, locals=None, fromlist=None):
>    # Fast path: see if the module has already been imported.
>    try:
>        return sys.modules[name]
>    except KeyError:
>        pass
>
>I was wondering if the formulation
>
>    if name in sys.modules:
>        return sys.modules[name]
>
>would be equivalent. IOW, is using try/except here only a matter of
>style or a necessity?

Somewhere I read a text regarding 'try:' versus 'if'. If you take the 
probabitility into consideration, how many times the test will fail or 
succeed, there are two possibilities:
- If the test will fail only on very rare occasions: Use 'try:'. When 
the statement(s) in the try-path succeed, the try:/except: construct 
will not consume additional execution time (not even for the test). The 
statements will just be executed as they are. Only in the (rare) case of 
failure, the exception handling will take additional execution time (a 
considerably big amount). The fact, that in python it is not named 
'error handling', but 'exception handling' reflects this. The failure 
should be the exception, also in matters of occurrence.
- If the relation between success and failure is not predictable, or if 
the case of failure will be frequent, use 'if'. The failure of a 'try:' 
gives you a penalty in form of consumption of a high amount of execution 
time. So, in these constellations, it is better to accept the relatively 
small amount of execution time taken by the explicit test.

Obviously, you can use 'try:' only, if there is the possibility to 
produce an exception on failure. In the other cases you must use the 
explicit test by 'if'.


>I'm suspecting that maybe, in multithreaded environments, the second
>option may be subject to a race condition, if another thread removes
>name frome sys.modules between the if and the return, but as I'm not
>very familiar (yet) with Python threads, I'm not sure it is a real
>concern here.

Your idea sounds reasonable, but I also am not yet familiar with threads.


>And maybe there are other reasons I'm completely missing for prefering
>EAFP over LBYL here?

One reason might be what I described above.



Best regards,

Günther



More information about the Python-list mailing list