[Python]异常处理技术(二) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

   

    重复引起异常 Re-raising Exceptions

    有的时候清除工作需要对错误处理和正确处理是不同的,

[Python]异常处理技术(二)

。例如,数据库操作错误需要回滚事务,但是没有错误需要commit操作。这种情况下,你必须要捕获异常并且处理它。中间的层异常 需要被捕获取消之前执行的部分操作,然后继续传播给上层的错误处理。

    #!/usr/bin/env python

    """Illustrate database transaction management using sqlite3.

    """

    import logging

    import os

    import sqlite3

    import sys

    DB_NAME = 'mydb.sqlite'

    logging.basicConfig(level=logging.INFO)

    log = logging.getLogger('db_example')

    def throws():

    raise RuntimeError('this is the error message')

    def create_tables(cursor):

    log.info('Creating tables')

    cursor.execute("create table module (name text, description text)")

    def insert_data(cursor):

    for module, description in [('logging', 'error reporting and auditing'),

    ('os', 'Operating system services'),

    ('sqlite3', 'SQLite database access'),

    ('sys', 'Runtime services'),

    ]:

    log.info('Inserting %s (%s)', module, description)

    cursor.execute("insert into module values (?, ?)", (module, description))

    return

    def do_database_work(do_create):

    db = sqlite3.connect(DB_NAME)

    try:

    cursor = db.cursor()

    if do_create:

    create_tables(cursor)

    insert_data(cursor)

    throws()

    except:

    db.rollback()

    log.error('Rolling back transaction')

    raise

    else:

    log.info('Committing transaction')

    db.commit()

    return

    def main():

    do_create = not os.path.exists(DB_NAME)

    try:

    do_database_work(do_create)

    except Exception, err:

    log.exception('Error while doing database work')

    return 1

    else:

    return 0

    if __name__ == '__main__':

    sys.exit(main())

    这个案例中在do_database_work()中使用了一个分离的异常处理,取消之前的数据库操作,然后全局的异常处理器会打印出错误信息。

    $ python sqlite_error.py

    INFO:db_example:Creating tables

    INFO:db_example:Inserting logging (error reporting and auditing)

    INFO:db_example:Inserting os (Operating system services)

    INFO:db_example:Inserting sqlite3 (SQLite database access)

    INFO:db_example:Inserting sys (Runtime services)

    ERROR:db_example:Rolling back transaction

    ERROR:db_example:Error while doing database work

    Traceback (most recent call last):

    File "sqlite_error.py", line 51, in main

    do_database_work(do_create)

    File "sqlite_error.py", line 38, in do_database_work

    throws()

    File "sqlite_error.py", line 15, in throws

    raise RuntimeError('this is the error message')

    RuntimeError: this is the error message

    保留错误跟踪信息 Preserving Tracebacks

    很多时候在你的程序中,异常中清理程序自己又引起了其他的异常,

电脑资料

[Python]异常处理技术(二)》(https://www.unjs.com)。这种情况一般是发生在系统资源(内存,硬盘资源等..)不足的时候。在异常处理中引起的异常可能会覆盖了原先根本的异常,如果没有对这些异常中的异常没有被处理。

    #!/usr/bin/env python

    import sys

    import traceback

    def throws():

    raise RuntimeError('error from throws')

    def nested():

    try:

    throws()

    except:

    cleanup()

    raise

    def cleanup():

    raise RuntimeError('error from cleanup')

    def main():

    try:

    nested()

    return 0

    except Exception, err:

    traceback.print_exc()

    return 1

    if __name__ == '__main__':

    sys.exit(main())

    当在处理原本错误的时候,cleanup()方法引起一个异常,那么异常处理机制就会重置去处理新的错误。(所以我们只看到异常中的异常了,原本引起的异常就没有了)

    $ python masking_exceptions.py

    Traceback (most recent call last):

    File "masking_exceptions.py", line 21, in main

    nested()

    File "masking_exceptions.py", line 13, in nested

    cleanup()

    File "masking_exceptions.py", line 17, in cleanup

    raise RuntimeError('error from cleanup')

    RuntimeError: error from cleanup

    即使第二个异常被捕获了,也没法保证原本的异常被保存。

    #!/usr/bin/env python

    import sys

    import traceback

    def throws():

    raise RuntimeError('error from throws')

    def nested():

    try:

    throws()

    except:

    try:

    cleanup()

    except:

    pass # ignore errors in cleanup

    raise # we want to re-raise the original error

    def cleanup():

最新文章