python异常

python使用异常对象来表示异常状态,并在错误时引发异常,异常未被捕获或处理,程序将终止并显示错误信息。

引发异常

使用raise语句并将一个类(必须时Exception的子类)或实例作为一个参数,将类作为一个参数时,将自动创建一个实例。

python中有一些常见内置异常类

异常名称

描述

Exception

常规错误的基类

ZeroDivisionError

除(或取模)第二参数为零 (所有数据类型)

AttributeError

引用属性或给它赋值失败

OSError

操作系统错误

IndexError

序列中没有此索引(index)

KeyError

映射中没有这个键

NameError

未声明/初始化对象 (没有属性)

SyntaxError

Python 语法错误,代码不正确

TypeError

对类型无效的操作

ValueError

传入无效的参数

还可以自定义异常类,但必须直接或间接的继承Exception

class someException(Exception):

    pass
#自定义异常类
class SortInputException(Exception):
    def __init__(self, length, latest):
        self.length = length
        self.latest = latest


def main():
    try:
        s = input("enter:")
        if len(s) >= 3:
            raise SortInputException(len(s), 3)
    except SortInputException as res:
        print("输入的字符长度为:{0},默认长度应该小于:{1}".format(res.length, res.latest))

    else:
        print("nothing to do")


main()

捕获异常

捕获异常也就是对异常进行处理,可用try/except来实现:

>>> try:

    x = input('Enter the first number: ')

    y = input('Enter the second number: ')

    print(int(x)/int(y)) #需要转换为整型

  except ZeroDivisionError:

      print("The second number can't be zero!")

    

Enter the first number: 10

Enter the second number: 0

The second number can't be zero!

捕捉异常并重新引发---用raise实现

>>> class MuffledCalculator:

    muffled = False #屏蔽开关的标志

    def calc(self,expr):

        try:

            return eval(expr)

        except ZeroDivisionError:

            if self.muffled: #若屏蔽开着,则捕捉异常并进行处理

                print('Division by zero is illegal')

            else:

                raise #raise重新引发异常

        

>>> mc = MuffledCalculator()

>>> mc.calc('10/0') #屏蔽机制未打开,因为muffled = False

Traceback (most recent call last):

File "<pyshell#31>", line 1, in <module>

calculator.calc('10/0')

File "<pyshell#27>", line 5, in calc

return eval(expr)

File "<string>", line 1, in <module>

ZeroDivisionError: int division or modulo by zero

 

>>> mc.muffled = True #打开屏蔽机制

>>> mc.calc('10/0')

Division by zero is illegal

如上如果启用了屏蔽机制,方法calc将会隐式的返回None,也就是不依赖返回值了。关闭屏蔽机制时,捕获了异常ZeroDivisionError,但是它继续向上传播。如果无法处理异常,可以在except子句中使用不带参数的raise即可。

当引发其他异常的时候,except的子句的异常会被作为异常上下文存储起来。可以使用raise...from...语句来提供自己的上下文,使用None禁用上下文:

多个except子句,捕捉多个不同类型的异常(此处不必类型转换)

>>> try:

    x = input('Enter the first number: ')

    y = input('Enter the second number: ')

    print(x/y)

  except ZeroDivisionError:

      print("The second number can't be zero!")

  except TypeError:

      print("That wasn't a number. was it? ")

    

Enter the first number: 2

Enter the second number: wsf

That wasn't a number. was it?

一个块捕捉两个异常,一个元组中指定这些异常

>>> try:

    x = input('Enter the first number: ')

    y = input('Enter the second number: ')

    print(int(x)/int(y))

  except(ZeroDivisionError,TypeError,NameErrror): #NameError找不到名字(变量)时引发

      print('Your numbers were bogus....')

捕捉对象---让程序继续运行并记录错误

except子句中访问异常对象本身,得使用两个参数,而不是一个

注意:在捕获多个异常时,也只是向except提供了一个参数,元组。

>>> try:

    x = int(input('Enter the first number: '))

    y = int(input('Enter the second number: '))

    print(x / y)

  except (ZeroDivisionError, TypeError) as e:

      print(e)

    

Enter the first number: 1

Enter the second number: 0

division by zero

捕捉所有的异常,except后不指定任何异常类即可。但是这样使用会隐藏没考虑过的错误不推荐。更好的选择是使用except Except as e并对异常对象进行检查。这样也会使得不是从Except类派生而来的异常漏掉。像SystemExit和KeyboradInterrupt都是从BaseExcept(Except的超类)派生而来的。

>>> try:

    x = input('Enter the first number: ')

    y = input('Enter the second number: ')

    print(x/y)

  except:

      print('Something wrong happened...')

    

Enter the first number: "This" is "completely" illegal 123

Enter the second number: 2

Something wrong happened...

给try/except语句添加一个else子句:

>>> try:

    print('A simple task')

  except:

      print('What? Something went wrong?')

  else:

      print('Ah...It went as planned.')

    

A simple task

Ah...It went as planned.

当没有发生异常使用break跳出循环

>>> while True:

    try:

        x = input('Enter the first number: ')

        y = input('Enter the second number: ')

        value = int(x)/int(y)

        print('x/y is', value)

    except:

        print('Invalid input, Please try again.')

    else:

        break

 

Enter the first number: test

Enter the second number: 1

Invalid input, Please try again.

Enter the first number: 10

Enter the second number: 2

x/y is 5.0

使用try/except Exception,e /else

>>> while True:

    try:

        x = input('Enter the first number: ')

        y = input('Enter the second number: ')

        value = int(x)/int(y)

        print('x/y is', value)

    except Exception as e: #python 3.0的写法

        print('Invalid input: ',e)

        print('Please try again')

    else:

        break
 

Enter the first number: 1

Enter the second number: 0

Invalid input: int division or modulo by zero

Please try again

Enter the first number: 'x'

Enter the second number: 'y'

Invalid input: invalid literal for int() with base 10: "'x'"

Please try again

Enter the first number: quux

Enter the second number: 2

Invalid input: invalid literal for int() with base 10: 'quux'

Please try again

Enter the first number: 10

Enter the second number: 2

x/y is 5.0

使用try/finally,不管try中发生什么,最后finally都会被执行

>>> try:

    x = 1/0

  finally: #finally子句肯定会被执行

      print('Cleaning up...')

      del x

    

Cleaning up...

Traceback (most recent call last):

File "<pyshell#25>", line 2, in <module>

x = 1/0

ZeroDivisionError: int division or modulo by zero

一条语句可以同时包含try/except/else/finally (或者其中3个)

>>> try:

    1/0

  except NameError:

      print("Unknown variable")

  else:

      print("That went well!")

  finally:

      print("Cleaning up.")

异常和函数

>>> def describePerson(Person):

        print('Description of', person['name'])

        print('Age:', Person['age'])

        try:

            print('Occupation:' , person['occupation']) #直接假设存在occupation键,如果不存在则引发异常

        except KeyError:

            pass

 

>>> person = {'name': 'Jack', 'age': 34}

>>> describePerson(person)

Description of Jack

Age: 34    

查看对象是否存在特定特性时,try/except很有用

>>> try:

        obj.write

    except AttributeError:

        print('The Object is not writeable')

    else:

        print('The Object is writeable')

警告,类似与异常,但通常只打印一条错误消息,可以指定警告级别,它们是Warning的子类。

还可以使用warnings模块中的函数filterwarnings来抑制警告,并指定采取的措施,比如ignore和error。另外可以根据异常来过滤掉特定类型的警告。

原文地址:https://www.cnblogs.com/whych/p/9654950.html