Python知识点整理(异常篇)

异常

对异常的最好描述是: 它是因为程序出现了错误而在正常控制流以外采取的行为. 这个行为又分为两个阶段: 首先是引起异常发生的错误, 然后是检测(和采取可能的措施)阶段.

异常的检测和处理

try-except语句

try:
    try_suite # watch for exceptions here 监控这里的异常
except Exception[, reason]:
    except_suite # exception-handling code 异常处理代码

关键词: 忽略代码, 继续执行, 和向上移交
try 语句块中异常发生点后的剩余语句永远不会被执行. 一旦一个异常被引发, 就必须决定控制流下一步到达的位置. 剩余代码将被忽略,解释器将搜索处理器, 一旦找到,就开始执行处理器中的代码.如果没有找到合适的处理器,那么异常就向上移交给调用者去处理,这意味着堆栈框架立即回到之前的那个.
如果在上层调用者也没找到对应处理器,该异常会继续被向上移交, 直到找到合适处理器.如果到达最顶层仍然没有找到对应处理器,那么就认为这个异常是未处理的, Python 解释器会显示出跟踪返回消息, 然后退出。

带有多个except的try语句

<span style="font-size:10px;">try:
    try_suite # watch for exceptions here 监控这里的异常
except Exception1[, reason1]:
    suite_for_exception_Exception1
except Exception2[, reason2]:
    suite_for_exception_Exception2</span>

处理多个异常的except语句

我们还可以在一个 except 子句里处理多个异常. except 语句在处理多个异常时要求异常被放在一个元组里:
try:
    try_suite # watch for exceptions here 监控这里的异常
except (Exception1, Exception2)[, reason]:
    suite_for_Exception1_and_Exception2

捕获所有异常

try:
    try_suite # watch for exceptions here 监控这里的异常
except BaseException, e:
    pass

不要尝试捕获所有异常,这样可能会忽略正确的错误。

else字句和finally字句

在 try 范围中没有异常被检测到时,执行 else 子句。
finally 子句是无论异常是否发生,是否捕捉都会执行的一段代码(例如关闭打开的文件),但是finally部分的字句可能会引发异常。

触发异常

程序员在编写 API 时也希望在遇到错误的输入时触发异常,为此,Python 提供了一种机制让程序员明确的触发异常:这就是 raise 语句。

raise语句

自定义异常类

#!/usr/bin/env python
'''
$Id$

myexc.py -- "my exceptions" demo which highlights user-created
    exceptions.  NOTE:  this example does not currently work with
    JPython as neither the errno nor tempfile modules have been
    implemented, and also, the socket module is incomplete.
'''

# import all our needed modules
import os, socket, errno, types, tempfile

# create our a new NetworkError exception, derived from IOError
class NetworkError(IOError):
    pass

# create our a new FileError exception, derived from IOError
class FileError(IOError):
    pass

# updArgs --> tuple
def updArgs(args, newarg=None):
    '''updArgs(args, newarg=None) -- if instance, grab each exception
        instance argument and place them in a list; otherwise, just
        convert given args sequence to a list for mutability; add
        newarg if necessary; then convert the whole thing to a tuple.'''

    if isinstance(args, IOError):
		myargs = []
		myargs.extend([arg for arg in args])
    else:
        myargs = list(args)

    if newarg:
        myargs.append(newarg)

    return tuple(myargs)


# fileArgs --> tuple
def fileArgs(fn, mode, args):
    '''fileArgs(fn, mode, args) -- similar to updArgs() except made
        specifically for files; creates small permission string and
        formats error to be similar to other IOError exceptions.'''

    if args[0] == errno.EACCES and \
            'access' in dir(os):
        perms = ''
        permd = { 'r': os.R_OK, 'w': os.W_OK, \
                    'x': os.X_OK }
        pkeys = permd.keys()
        pkeys.sort()
        pkeys.reverse()

        for eachPerm in 'rwx':
            if os.access(fn, permd[eachPerm]):
                perms = perms + eachPerm
            else:
                perms = perms + '-'

        if isinstance(args, IOError):
            myargs = []
	    myargs.extend([arg for arg in args])
        else:
            myargs = list(args)

        myargs[1] = "'%s' %s (perms: '%s')" % \
                    (mode, myargs[1], perms)

        myargs.append(args.filename)

    else:
        myargs = args

    return tuple(myargs)

# myconnect() --> None (raises exception on error)
def myconnect(sock, host, port):
    '''myconnect(sock, host, port) -- attempt to make a network connection
    with the given socket and host-port pair; raises our new NetworkError
    exception and collates error number and reason.'''

    try:
        sock.connect((host, port))

    except socket.error, args:
        myargs = updArgs(args)        # convert inst to tuple
        if len(myargs) == 1:        # no #s on some errors
            myargs = (errno.ENXIO, myargs[0])

        raise NetworkError, \
            updArgs(myargs, host + ':' + str(port))


# myopen() --> file object
def myopen(fn, mode='r'):
    '''myopen(fn, mode) -- wrapper around the open() built-in function
    such that we raise our new FileError exception on an error situation
    and collate a set of FileError exception arguments to pass to the user'''

    try:
        fo = open(fn, mode)

    except IOError, args:
		print "IOError occur"
		raise FileError, fileArgs(fn, mode, args)

    return fo


# testfile() --> None
def testfile():
    '''testfile() -- runs the file tester, setting a variety of test files
    which should generate FileError exceptions'''

    fn = tempfile.mktemp()      #make temp file and path
    f = open(fn, 'w')
    f.close()

    for eachTest in ((0, 'r'), (0100, 'r'), (0400, 'w'), (0500, 'w')):
        try:
            os.chmod(fn, eachTest[0])
            f = myopen(fn, eachTest[1])
        except FileError, args:
            print "%s: %s" % \
                    (args.__class__.__name__, args)
        else: 
            print fn, "opened ok... perms ignored"
            f.close()

    os.chmod(fn, 0777)
    os.unlink(fn)


# testnet() --> None
def testnet():
    '''testfile() -- runs the network tester, making various connections
    which should generate NetworkError exceptions'''
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    for eachHost in ('127.0.0.1', 'www'):
        try:
            myconnect(s, eachHost, 80)
        except NetworkError, args:
            print "%s: %s" % (args.__class__.__name__, args)
        else:
            print "network connection successful to", `eachHost`
            s.close()


# run tests if invoked as a script
if __name__ == '__main__':
    testfile()
    testnet()


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值