如何确定特定异常类定义的模块
注意:我修改了我的问题标题,让它更准确地反映我真正想知道的内容。在最初的标题和问题内容中,我提到了抛出异常的来源;我想说的是,应该提到异常类定义所在的模块。这一点可以通过下面的回答看到,原问题的答案是异常是从cursor.execute和cursor.next的调用中抛出的——这当然不是你写try/except块所需的信息。
举个例子(这个问题和SQLite或PySQLite模块没有直接关系):
from pysqlite2 import dbapi2 as SQ
try:
cursor.execute('CREATE TABLE pname (id INTEGER PRIMARY KEY, name VARCHARS(50)')
except SQ.OperationalError:
print("{0}, {1}".format("table already exists", "... 'CREATE' ignored"))
#
cursor.execute('SELECT * FROM pname')
while 1:
try:
print(cursor.next())
except StopIteration:
break
#
我让这两个代码片段出错,以查看抛出的异常,然后编写了try/finally块——但这并没有告诉我异常类是在哪个模块中定义的。在我的例子中,只有一个导入的模块,但如果有更多模块,我想知道一个有经验的Python程序员是如何识别异常来源的(目前我的方法是搜索文档,直到我碰巧找到为止)。
[是的,我知道在SO上有一个几乎相同的问题——但那是关于C#的,而不是Python,而且如果你读了作者修改后的版本,你会发现他有不同的问题要解决。]
5 个回答
你可以使用Python的inspect
模块和通用的异常处理,方法如下:
from inspect import getmodule
try:
# attempt some task
except Exception, e:
print getmodule(e)
这样做会输出模块及其路径,结果如下:
<module 'some.module' from '/path/to/some/module.pyc'>
通常情况下,我会直接查看文档。Python模块或函数的文档中会有一部分是列出它定义的异常。如果没有列出任何异常,我就会假设我需要找的是Python内置的异常。
顺便提一下,StopIteration异常是Python中任何“可迭代”对象用来告诉你数据已经到头的标准方式。这个循环:
cursor.execute('SELECT * FROM pname')
while 1:
try:
print(cursor.next())
except StopIteration:
break
可以写成:
cursor.execute('SELECT * FROM pname')
for x in cursor:
print(x)
编辑:我得说,尽管我很自信地认为异常会有文档说明,但我在Python的文档帮助或dbapi2的网页帮助中找不到这样的列表。在这种情况下,我想我就像你一样:在谷歌上搜索这个异常的名字,看看能找到什么!
第二个[[异常被抛出]]是来自Python的核心模块
这不对:它是从cursor.next
的调用中抛出的,正好和第一个异常是从cursor.execute
的调用中抛出的一样——很难理解你为什么会这么断言,但这与事实相悖,依然是事实。
如果你是在说某个异常类是在哪个模块中定义的,而不是你所说的它是从哪里抛出的,那当然是完全不同的事情:
try:
...whatever...
except Exception, e:
print "caught an exception defined in module", e.__class__.__module__
内置异常实际上是在exceptions
模块中定义的,这段代码也会告诉你。当然,一旦你有了模块名(这段代码给了你),你可以进一步探索,比如获取模块对象(只需通过模块名索引sys.modules
)等等。