0

为了清楚起见,我正在编辑问题。

我在导入 MySQLdb 的模块中创建了一个类。我发现如果用户传递给我的类的表不存在,MySQLdb 将引发异常。我正在捕获该异常,并将一个新异常传递给客户。但即使客户端捕捉到我的异常,程序仍然会终止。我也尝试将相同的异常 MySQLdb 传递给客户端。

由于客户端将在循环中调用我的方法,并传入各种表名,因此如果表名不好,我不希望程序阻塞。我希望客户的迭代继续到下一个有效的表名。这是一个片段(tableName 是传递给该方法的参数):

在我的班级/模块中:

    self.tableName = 表名
    尝试:       
        self.cursor.execute("select * from " + self.tableName + ";") #如果表不存在会抛出异常。
    除了:
        raise MyException("\n*** " + self.tableName + " 不存在。***")

在客户端:

    表 = ["BadTableName", "GoodTableNameA", "GoodTableNameB","GoodTableNameC"]

    尝试:
        对于表格中的表格:
            my_method(table) #Exception 消息通过 BadTableName 传入,但程序结束。此循环的子序列迭代永远不会发生
    除了例外,e:
        打印 e

即使在调用 my_method(BadTableName) 之后,我也希望客户端继续。

顺便说一句,my_method() 是在客户端导入的其自己的模块中定义的类的一部分。

谢谢你。

4

5 回答 5

1

异常并不总是导致程序结束。从文档

在执行过程中检测到的错误称为异常并且不是无条件致命的:

如果在 try: except 块中引发异常并且except子句指定异常或异常的超类,它将被处理。

在处理异常时,您可以检查它并找出与之相关的所有信息。我以前从未使用过该traceback模块,但它看起来包含您需要的一切。

我想您的第二个问题取决于您希望用户看到的内容。是否应该显示异常?(您可以访问回溯)。应该只显示消息吗?你应该记录回溯吗?

于 2013-02-22T20:00:06.900 回答
1

添加到其他答案:未捕获的异常将终止程序,但仅在执行适用的finally(如果有)和任何atexit处理程序之后。所以原则上,可以在未捕获的异常之后无限期地继续执行。

但是,没有一类异常只会打印错误消息并按其性质继续执行。如果需要,请使用警告

于 2013-02-22T20:06:06.863 回答
0

捕获的异常将终止程序。捕获的异常不会

如果捕获到异常,可以使用 traceback 模块输出堆栈跟踪:

http://docs.python.org/2/library/traceback.html#traceback-examples

于 2013-02-22T20:00:45.497 回答
0

1)不,引发异常并不总是导致程序终止。未捕获的异常会导致程序终止。您可以使用块包围代码try/except,如下所示,以阻止异常向上传播堆栈。

try:
    file = open("foo.txt")
except IOError:
    file = None

2)实际捕获异常的代码可以访问异常的原始堆栈帧,并且可以决定如何处理它。

使用原始回溯重新引发错误:

try:
    some_function()
except IOError as e:
    raise

使用新的回溯重新引发错误(几乎没有第一种情况有用):

try:
    some_function()
except IOError as e:
    raise e

不要重新引发,并打印异常和回溯:

try:
    some_function()
except IOError as e:
    import traceback
    traceback.print_exc()
于 2013-02-22T19:58:48.277 回答
0

阅读您编辑的问题后,我不确定您遇到了两个问题中的哪一个。


如果您的问题只是您只想要一个异常来终止一个循环迭代而不是整个循环,那么只需以明显的方式重新嵌套语句即可。而不是这个:

try:
    for table in tables:
        my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen
except Exception, e:
    print e

做这个:

for table in tables:
    try:
        my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen
    except Exception, e:
        print e

另一方面,如果问题是客户端没有捕获异常,那么问题很可能是您MyException的不是Exception. 至少有三种方式会发生这种情况。

由于您使用的是旧式except语法 ( except Exception, e:) 而不是新式 ( except Exception as e:),因此您可能使用的是较旧的 Python 版本,它允许您引发不继承自BaseException. 例如:

class MyException(object):
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

根据您的 Python 版本,这可能无法引发MyException,而是引发 a TypeError(' Out[11]: TypeError('exceptions must be old-style classes or derived from BaseException, not MyException')(这将被捕获),或打印警告,或者只是按照您的要求默默地“工作”(这意味着您没有捕获任何东西,而您的程序退出并回溯)。


同时,即使在 2.7 中,您仍然可以提出旧式类,也不会被捕获:

class MyException:
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

这将始终无法捕获异常,并且您的应用程序将退出并带有回溯。


最后,如果你继承自BaseException而不是Exception,那么显然Exception不会抓住它。

class MyException(BaseException):
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

再一次,这将始终无法捕获您提出的内容,并且您将退出并进行回溯。

于 2013-02-22T20:50:34.087 回答