zoukankan      html  css  js  c++  java
  • Python基础教程【读书笔记】

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴!

    第三波:第8章  异常

    [总览]学习如何创建和引发自定义的异常,以及处理异常的各种方法。

      为了能够处理异常事件,可以再所有可能发生这类事件的地方都使用条件语句,但是这么做可能不仅会没效率和不灵活,而且还会让程序难以阅读。Python的异常对象提供了非常强大的替代解决方案。

    [8.1] 什么是异常

      Python用异常对象(exception object)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行。

      事实上,每个异常都是一些类的实例,这些实例可以被引发,并且可以用多种方法进行捕捉,使得程序可以捉住错误并且对其进行处理,而不是让整个程序失败。

    [8.2] 按自己的方式出错

      异常可以在某些东西出错时自动引发。先学习如何引发异常---甚至创建自己的异常类型。


    [8.2.1] raise语句

      为了引发异常,可以使用一个类(应该是Exception的子类)或者实例参数调用raise语句。使用类时没程序会自动创建实例。如下使用内建的Exception异常类:

      raise Exception

      raise Exception('Hyperdrive overload')

      第一个例子raise Exception引发一个没有任何有关错误信息的普通异常,后一个例子中,则添加了一些hyperdive overload错误信息。

      内建的异常类有很多,内建异常都可以再exception模块中找到。使用dir函数列出模块的内容:

      import exception

      dir(exception)

      所有这些异常都可以用在raise语句中:

      raise ArithmeticError

    表8-1 一些内建异常

      类名                  描述

      Exception               所有异常的基类

      AttributeError              特性引用或赋值失败时引发

      IOError                试图打开不存在文件时引发

      IndexError               在使用序列中不存在的索引时引发

      KeyError                在使用映射中不存在的键时引发

      NameError               在找不到名字(变量)时引发

      SyntaxError               在代码为错误形式时引发

      TypeError                在内建操作或者函数应用于错误类型的对象时引发

      ValueError               在内建操作或者函数应用于正确类型的对象,但该对象使用不合适的值时引发 

      ZeroDivisionError           在除法或者模除操作的第二个参数为0时引发

    [8.2.2] 自定义异常类

      有些时候创建自己的异常类。那么如何创建自己的异常类呢?只是要确保从Exception类继承(不管是间接的或者是直接的,也就是说继承其他的内建异常类也是可以的),编写一个自定义异常类基本上如下:

      class SomeCustomException(Exception):pass

    [8.3] 捕捉异常

      关于异常最有意思的地方就是可以处理它们(通常叫做诱捕或者捕捉异常),可以使用try/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!"

      看起来用if语句检查y值会更简单一些,但是如果需要给程序加入更多除法,那么就得给每个除法加个if语句。而使用try/except的话只需要一个错误处理器。

      如果捕捉到了有慈航,但是又想重新引发它(也就是说要传递异常),那么可以调用不带参数的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

    [8.4] 不止一个except子句

      可以再同一个try/except语句后面加上另一个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 wan't a number ,was it?"

      应该注意到,异常处理并不会将搞乱原来的代码,而增加一大堆if语句检查可能的错误情况会让代码相当难度。

    [8.5] 用一个块捕捉两个异常

       如果需要用一个块捕捉多个类型异常,那么可以将它们作为元组列出,像下面这样:

      try:

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

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

        print x/y

      except (ZeroDivisionError,TypeError,NameError):

        print 'Your number were bogus...'

      注意except子句中异常对象外面的圆括号很重要。忽略它们是一种常见的错误。

    [8.6] 捕捉对象

      如果希望在except子句访问异常对象本身,可以使用两个参数。注意,就算捕捉到多个异常,也只需向except子句提供一个参数。如果想让程序继续运行,但是又因为某种原因想记录下错误,这个功能就很有用。

      try:

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

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

        print x/y

      except (ZeroDivisionError,TypeError),e:

        print e

    [8.7] 真正的全捕捉

      如果真的想用一段代码捕捉所有异常,那么可以在except子句中忽略所有的异常类:

      try:

        ......

      except:

        print 'Something wrong happened...'

      这样捕捉所有异常时危险的,因为它会隐藏所有程序员未想到并未做好准备处理的错误。

    [8.8] 万事大吉

      可以像对条件和循环语句那样,给try/except语句价格else子句:

      try:

        print 'A simple task'

      except:

        print 'What? Something went wrong!'

      else:

        print 'Ah...It went as planned!'

    [8.9] 最后......

      最后是finally子句,它可以用来在可能的异常后进行清理,它和try子句联合使用:

      x=None

      try:

        x=1/0

      finally:

        print 'Cleaning up...'

        del x

      上面的代码中,finally子句肯定会被执行,不管try子句中是否发生异常。因为使用del语句删除一个变量是非常不负责的清理手段,所以finally子句用于关闭文件或者网络套接字时会非常有用。还可以在同一条语句中组合使用try、except、finally和else。

      try:

        1/0

      except NameError:

        print 'Unknown variable'

      else:

        print "That went well!"

      finally:

        print "Cleaning up....."

    [8.10] 异常和函数

      异常和函数能很自然地一起工作。如果异常在函数内引发而不被处理,它就会传播至函数调用的地方。如果在那里也没有处理异常,它就会继续传播,一直到达主程序(全局作用域)。如果那里没有异常处理程序,程序会带着堆栈跟踪中止。

    [8.11] 异常之禅

      异常处理并不是很复杂。如果知道某段代码可能会导致某种异常,而又不希望程序以堆栈跟踪的形式终止,那么久根据需要添加try/except或者try/finally语句进行处理。

    [8.12] 小结

      异常对象:异常情况可以用异常对象表示。

      警告:警告类似于异常,但是一般来说仅仅打印错误信息。

      引发异常:可以使用raise语句引发异常。它接受异常类或者异常实例作为参数,还能提供两个参数(异常和错误信息)。

      自定义异常类:用继承Exception类的方法可以创建自己的异常类。

      捕捉异常:使用try语句的except子句捕捉异常。异常可以放在元组中以实现多个异常的制定。如果给except提供两个参数,第2个参数就会绑定到异常对象上。同样,在一个try/except语句中能包含多个except子句,用来分别处理不同的异常。

      else子句:如果主try块中没有引发异常,else子句就会被执行。

      finally:如果需要确保某些代码不管是否有异常引发都要执行,那么这些代码可以防止在finally子句中。

      异常和函数:在函数内引发异常时,它就会被传播到函数调用的地方。

  • 相关阅读:
    头文件#ifndef #define #endif使用
    Django框架【form组件】
    数据库【mysql】之pymysql
    数据库【mysql篇】典型的一些练习题目
    Python开发【socket篇】解决粘包
    Python开发【内置模块篇】os模块
    Python开发【内置模块篇】日志模块
    Python开发【内置模块篇】configparser
    Python开发【内置模块篇】collections
    Python开发【内置模块篇】datetime
  • 原文地址:https://www.cnblogs.com/pythonMLer/p/5642161.html
Copyright © 2011-2022 走看看