If you run the module as a script (i.e. provide its name to the interpreter and not import it), it will be loaded under the module name __main__ .
If you then import the same module from your program, reload it and reinstall it under its real name. If you are not careful, you may end up doing something twice.
http://effbot.org/zone/import-confusion.htm
You download file1.py twice as two separate modules. The first time it loads as the result of your command line:
python file1.py
In this case, the file1.py is loaded as the main module, __main__ .
The second time you load it as a result of your import statement:
from file1 import TestException
In this case, file1.py is loaded as module file1 .
Since file1.py is loaded as two different modules, it has two different copies. Especially __main__.TestException is different from file1.TestException .
So, inside the __main__ line:
except TestException as e:
catches __main__.TestException , even when tfun() raises __file1__.TestException . Inside file1 this same line catches file1.TestException .
In the first case, the types do not match, and the except: clause except: not executed; in the latter case, the type matches, and the condition except: is satisfied.
Perhaps this program can make it more clear what is happening:
from file2 import tfun class TestException(Exception): pass try: print 'I am calling file2.tfun from', __name__ tfun() print 'I have called file2.tfun from', __name__ except TestException as e: print 'I am caught in %s'%(__name__) print type(e), TestException except Exception as e: print 'I am generally caught in %s'%__name__ print type(e), TestException print 'I am exiting from',__name__
Result:
$ python file1.py I am calling file2.tfun from __main__ I am calling file2.tfun from file1 I am caught in file1 <class 'file1.TestException'> <class 'file1.TestException'> I am exiting from file1 I am generally caught in __main__ <class 'file1.TestException'> <class '__main__.TestException'> I am exiting from __main__
A simple workaround is to modify file2.py file:
def tfun(): from __main__ import TestException raise TestException()
Result:
$ python file1.py I am calling file2.tfun from __main__ I am caught in __main__ <class '__main__.TestException'> <class '__main__.TestException'> I am exiting from __main__