Python 异常执行两次,并被另一个except块捕获
我有以下代码: file1.pyPython 异常执行两次,并被另一个except块捕获,python,exception,recursion,import,Python,Exception,Recursion,Import,我有以下代码: 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'
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)
def tfun():
from file1 import TestException
raise TestException()
file2.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)
def tfun():
from file1 import TestException
raise TestException()
python file1.py的输出如下所示:
I am running
I am running
I am caught
<class 'file1.TestException'>
I am generally caught
<class 'file1.TestException'>
我正在跑步
我在跑步
我被抓住了
我通常被抓住了
首先,为什么在这种情况下代码会执行两次?我可以理解导入是递归的,但是为什么脚本的代码会再次执行呢
其次,第二次它没有被相同的块捕获,除了
块,即使它与第一次的类型相同,我也找不到解释
最后,我试图在不将任何内容移动到新文件的情况下找到解决此问题的方法,但我认为它似乎没有任何效果。有可能克服这个问题吗
编辑
对于第二个问题,我意识到这是因为代码在模块级别内
如果您将模块作为脚本运行(即,将其名称提供给解释器,而不是导入它),它将加载在模块名称\uuuu main\uuu
下
如果随后从程序中导入相同的模块,它将以其真实名称重新加载和执行。如果你不小心,你可能会做两次
您正在加载两次file1.py
,作为两个不同的模块。第一次作为命令行的结果加载时:
python file1.py
在这种情况下,file1.py将作为主模块加载,\uuuu main\uuuu
作为导入语句的结果第二次加载时:
from file1 import TestException
在这种情况下,file1.py将作为模块file1
加载
因为file1.py是作为两个不同的模块加载的,所以其中的所有内容都有两个不同的副本。尤其是\uuuu main\uuuu.TestException
不同于文件1.TestException
因此,在\uuuuu main\uuuuuu
中,行:
except TestException as e:
正在捕获\uuuuu main\uuuuuu.TestException
,即使tfun()
正在引发\uuuuuu file1\uuuuuuuu.TestException
。在file1
内部,同一行正在捕获file1.TestException
在前一种情况下,类型不匹配,except:
子句未运行;在后一种情况下,类型不匹配,并且运行except:
子句
也许这个计划可以让我们更清楚地了解正在发生的事情:
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__
结果:
$ 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__
$ 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__
结果:
$ 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__
$ 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__
$python file1.py
我正在从_main调用file2.tfun__
我陷入了困境__
我要离开梅因__
+1我认为,\uuuu main\uuu.TestException
和file1.TestException
之间的区别是最棘手的部分。+1对于一个简短、完整、独立的程序来说,它演示了手头的问题。参考:和