我有以下代码:
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()
,python file1.py
的输出如下:
I am running
I am running
I am caught
<class 'file1.TestException'>
I am generally caught
<class 'file1.TestException'>
首先,在这种情况下代码执行两次的原因是什么?我可以理解导入是递归的,但为什么脚本代码会再次执行?
其次,第二次它没有被同一except
块捕获,即使它与第一次类型相同,我也找不到解释。
最后,我试图找到解决此问题的方法而不将任何内容移动到新文件但我似乎没有任何问题。是否有可能克服这个问题?
修改
对于第二个问题,我意识到这是因为代码在模块级别内。
答案 0 :(得分:7)
如果您将模块作为脚本运行(即将其名称提供给解释器,而不是将其导入),则将其加载到模块名称
__main__
下。如果您从程序中导入相同的模块,则会以其真实名称重新加载并重新执行。如果你不小心,你最终可能会做两次事。
您正在加载file1.py
两次,作为两个不同的模块。它第一次作为命令行的替代加载:
python file1.py
在这种情况下,正在加载file1.py作为主模块__main__
。
第二次由于import语句而加载它:
from file1 import TestException
在这种情况下,正在加载file1.py作为模块file1
。
因为file1.py是作为两个不同的模块加载的,所以其中包含两个不同的副本。特别是__main__.TestException
与file1.TestException
不同。
所以,在__main__
内,行:
except TestException as e:
即使__main__.TestException
提出tfun()
,也会抓住__file1__.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__
一个简单的解决方法是修改file2.py:
def tfun():
from __main__ import TestException
raise TestException()
结果:
$ 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__