The exception is thrown twice, and it falls into another block

I have the following code:

file1.py

from file2 import tfun class TestException(Exception): pass try: print 'I am running' tfun() except TestException as e: print 'I am caught' print type(e) except Exception as e: print 'I am generally caught' print type(e) 

file2.py

 def tfun(): from file1 import TestException raise TestException() 

and the output from python file1.py as follows:

 I am running I am running I am caught <class 'file1.TestException'> I am generally caught <class 'file1.TestException'> 

First of all, why is the code executed twice in this case? I can understand that the import is recursive, but why is the script code executed again?

Secondly, the second time it does not fall into the same except block, even if it is the same type as the first time, which also cannot be explained.

Finally, I am trying to find a workaround for this problem without moving anything to the new file, but I don't think it is any. Is it possible to overcome this problem?

Edit

For the second question, I realized that this is because the code is inside the module level.

+6
source share
1 answer

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__ 
+7
source

Source: https://habr.com/ru/post/974475/


All Articles