• Python学习 Part6:错误和异常


    两种不同类型的错误:语法错误和异常

    1. 语法错误

    语法错误,也被称作解析错误:

    >>> while True print('Hello world')
    SyntaxError: invalid syntax

    2. 异常
    运行期间检测到的错误称为异常,并且程序不会无条件的崩溃。

    复制代码
    >>> 10*(1/0)
    Traceback (most recent call last):
      File "<pyshell#43>", line 1, in <module>
        10*(1/0)
    ZeroDivisionError: division by zero
    >>> 4+spam*3
    Traceback (most recent call last):
      File "<pyshell#44>", line 1, in <module>
        4+spam*3
    NameError: name 'spam' is not defined
    >>> '2'+2
    Traceback (most recent call last):
      File "<pyshell#45>", line 1, in <module>
        '2'+2
    TypeError: Can't convert 'int' object to str implicitly
    >>> 
    复制代码

    异常是以不同的类型出现的,并且类型也被当作信息的一部分打印出来:示例中包含ZeroDivisionError, NameError, TypeError类型。

    • 异常处理:
    复制代码
    >>> while True:
        try:
            x=int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops! That was not valid number. Try again...")
    
            
    Please enter a number: a
    Oops! That was not valid number. Try again...
    Please enter a number: ggdg
    Oops! That was not valid number. Try again...
    Please enter a number: 34
    >>> x
    34
    复制代码

    如果异常的类型与except后面的异常类型相匹配,那么except子句就会被执行。一个try语句可以有多个except子句,用来明确的处理不同的异常。一个except子句可以通过带括号的元组定义多个异常类型:

    except(RuntimeError,TypeError,NameError):
            pass

    try...:keyword:except语句有一个可选的else子句,如果存在,它必须在所有的except子句后面。如果try子句没有抛出异常,这对那些必须执行的代码就非常有用。

    复制代码
    for arg in sys.argv[1:]:
        try:
            f=open(arg,'r')
        except IOError:
            print('Cannot open', arg)
        else:
            print(arg,'has',len(f.readlines()),'lines')
            f.close()
    复制代码

    except子句可以在异常名称后面指定一个变量。

    复制代码
    >>> try:
        raise Exception('spam','eggs')
    except Exception as inst:
        print(type(inst))
        print(inst.args)
        print(inst)
    
        
    <class 'Exception'>
    ('spam', 'eggs')
    ('spam', 'eggs')
    复制代码
    • 抛出异常:

    raise语句允许程序员强制抛出一个指定的异常:

    >>> raise NameError('Hi There')
    Traceback (most recent call last):
      File "<pyshell#39>", line 1, in <module>
        raise NameError('Hi There')
    NameError: Hi There

    如果需要确定是否抛出了一个异常而并不想去处理它,一个简单的raise语句允许你重新抛出异常:

    复制代码
    >>> try:
        raise NameError('Hi There')
    except NameError:
        print('An exception flew by!')
        raise
    
    An exception flew by!
    Traceback (most recent call last):
      File "<pyshell#45>", line 2, in <module>
        raise NameError('Hi There')
    NameError: Hi There
    复制代码
    • 用户自定义异常:

    通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。

    复制代码
    >>> class MyError(Exception):
        def __init__(self,value):
            self.value=value
        def __str__(self):
            return repr(self.value)
    
        
    >>> 
    >>> try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:',e.value)
    
        
    My exception occurred, value: 4
    >>> raise MyError('opps!')
    Traceback (most recent call last):
      File "<pyshell#58>", line 1, in <module>
        raise MyError('opps!')
    MyError: 'opps!'
    >>> 
    复制代码
    • 定义清理动作

    try语句有另外一个可选的子句,可以用来定义那些在所有情况下必须执行的清理动作:

    复制代码
    >>> try:
        raise KeyboardInterrupt
    finally:
        print('Goodby, world!')
    
        
    Goodby, world!
    Traceback (most recent call last):
      File "<pyshell#63>", line 2, in <module>
        raise KeyboardInterrupt
    KeyboardInterrupt
    复制代码

    无论是否发生异常,一个finally子句在离开try语句前总是会被执行。当在try子句中发生一个异常并且没有被except子句处理时,它将会在finally子句执行完后被重新抛出。即使通过break,continue或者return等其他任何子句,当要离开try语句时,finally子句也会被执行。

    复制代码
    >>> def divide(x,y):
        try:
            result=x/y
        except ZeroDivisionError:
            print('Division by zero!')
        else:
            print("Result is", result)
        finally:
            print("Executting finally clause")
    
            
    >>> divide(2,1)
    Result is 2.0
    Executting finally clause
    >>> divide(2,0)
    Division by zero!
    Executting finally clause
    >>> divide("2","1")
    Executting finally clause
    Traceback (most recent call last):
      File "<pyshell#78>", line 1, in <module>
        divide("2","1")
      File "<pyshell#75>", line 3, in divide
        result=x/y
    TypeError: unsupported operand type(s) for /: 'str' and 'str'
    >>> 
    复制代码
    • 预定义的清理动作
    >>> for line in open("testing.txt"):
        print(line)

    上段代码的问题是当代码执行完毕后不知会过多久它才会关闭文件。with语句保证像文件这样的对象在使用完之后总是可以被立即正确的清理:

    >>> with open("testing.txt") as f:
        for line in f:
            print(line)
  • 相关阅读:
    四则运算 2
    《你的灯亮着吗》读后感 (前两篇)
    四则运算设计思路
    读书目标
    课堂总结
    人月神话感想
    软件工程概论11
    软件工程概论10
    bnu——GCD SUM (莫比乌斯反演)
    POJ1108_Split Windows 解题报告
  • 原文地址:https://www.cnblogs.com/zhangfeivip/p/8931447.html
Copyright © 2020-2023  润新知