• python基础-异常和模块


    1. 异常的定义

    #encoding=utf-8

    import sys

    try:

        1/0

        print "never executed!"

    except ZeroDivisionError,e:

        print "ZeroDivisionError occur"

    except IOError,e:

        print "IO Error occur"

    except:

        print "other Error occur!"

     

    print "Done"

     

     

    #encoding=utf-8

    import sys

    try:

        1/0

        print "never executed!"

    except ZeroDivisionError,e:

        print "ZeroDivisionError occur"

        print e.message

    except IOError,e:

        print "IO Error occur"

        

    except:

        print "other Error occur!"

     

    print "Done"

     

    线上监控:可以监控流量,监控日志

     

    也可以用traceback去捕获

    #encoding=utf-8
    import sys
    import traceback
    try:
        1/0
        print "never executed!"
    except ZeroDivisionError,e:
        print "ZeroDivisionError occur"
        print e.message
        print e.args
    except:
        print "other Error occur!"
    else:
        print "no Error occur!"

     

     

    要使程序很健壮,就必须处理好所有异常情况。

    捕获异常中可以再嵌套捕获异常,直到不会有新的异常发生为止。

    #encoding=utf-8
    import sys
    import traceback
    try:
        1/0
        print "never executed!"
        try:
            print "other Error occur!"
        except:
            print
            try:
    except ZeroDivisionError,e:
        print "ZeroDivisionError occur"
        print e.message
        print e.args
    except:
        try:
            print "other Error occur!"
        except:
            print
            try: 
    else:
        print "no Error occur!"
    print "Done"

    可以多层嵌套

     

    同时捕获多个异常:

    except ZeroDivisionError,IOError,TypeError,e:

        print "ZeroDivisionError occur"

        print e.message

    print e.args

     

    finally

    示例1:(try-else语句)
    按下ctrl+c会引发KeyboardInterrupt异常发生。
    #encoding=utf-8
    import sys
    try:
    s = raw_input('Enter something --> ')
    except KeyboardInterrupt:
    print ' Why did you do an Ctrl+c on me?' #ctrl+c
    sys.exit() # exit the program
    except:
    print ' Some error/exception occurred.' #ctrl+z 报错
    else:
    print "no exception occur!"
    finally:
    print "finally is executed!"
    注意: finally要放到else的后
    面,否则报语法错

    在try块中抛出一个异常,程序会立即执行finally块代码(如果有的话)。当finally
    块中的所有代码被执行结束后,异常才会被再次提出,并执行except块代码。
    finally和else语句块可以同时存在。如果发生异常只执行finally语句块,否则两语
    句块都会执行。

     

    小练习:
    1 用户输入一个文件的绝对路径
    2 如果没有异常,则打印文件的内容
    3 有异常,则重新让用户输入文件的绝对路径 

     

    #coding=utf-8

     

    while 1:

        file_path=raw_input("please input the file path:")

        try:

            fp=open(file_path)

            print fp.readline()

            fp.close()

            break

        except IOError:

            print "file path does not exists!"

            continue

    except Exception,e: 

     #出现什么错误就打印出来,把异常信息都封装到变量里,一般都写e 

     

            print e

            continue

     

     

    1. 异常的原理

    并不是所有出现异常没有被捕获到就会出现程序崩溃

    举例:

    #coding=utf-8

    def a():
        try:
            1/0
        except IOError,e:
            print e

    try:
        a()
    except Exception,e:
        print e 

    # 0作为分母的异常程序中用IOError捕获不到,但是上层的try在调用时又做了处理,这时是不会出现崩溃的。

     

    #coding=utf-8

    def a():
        try:
            1/0
        except IOError,e:
            print e

    a()

    但是这种上层也没有进行异常处理的,就会出现崩溃

     

    1. Python中使用关键字raise来自己触发异常

    #coding=utf-8

    def a():
        try:
            raise 
        except IOError,e:
            print e

    try:
        a()
    except Exception,e:
        print e

     

     

    #coding=utf-8

    def a():
        try:
            raise ZeroDivisionError
        except IOError,e:
            print "function exception occur!"
            print e

    try:
        a()
    except ZeroDivisionError,e:
        print "catch Exception"
        print e
        print "Done!" 

     

    #coding=utf-8
    def exceptionTest(num):
        if num < 0:
            raise Exception("Invalid num")
        else:
            print num
        if num == 0:
            raise ZeroDivisionError("integer division or modulo by zero")
    #调用函数,触发异常
    exceptionTest(-12)

     

    触发了异常且没有捕获,程序就会出现这样的错误。

     

    #coding=utf-8

    def exceptionTest(num):

        if num < 0:

            raise Exception("Invalid num")

        else:

            print num

        if num == 0:

            raise ZeroDivisionError("integer division or modulo by zero")

    #调用函数,触发异常

    try:

       exceptionTest(-12)

    except:

       pass

    exceptionTest(0)

     

    4.一个异常可以带上参数,可作为输出的异常信息参数。通过except语句来捕获异
    常的参数
    异常参数接收的异常值通常包含在异常的语句中。在元组的表单中变量可以接收
    一个或者多个值。元组通常包含错误字符串,错误数字,错误位置。

     

     

    1. 嵌套try的异常捕获示例

    #encoding=utf-8

    import sys

    try:

        try:

            1/0

        except IOError:

            print "IOError occur"

    except Exception,e:

    print e

     

     

     

    1. except可以不带参数,表示捕获所有的异常;如果加了特定的参数,表示捕获特定的
      异常。
      except参数可以有多个,每个参数间用逗号分隔。

    import sys
    try:
        1/0
    except (IOError,ZeroDivisionError),e:
        print "IOError or ZeroDivisionError occurs!"
        print e

     

     

    1. try块中抛出一个异常,程序会立即执行finally块代码(如果有的话)。当finally
      块中的所有代码被执行结束后,异常才会被再次提出,并执行except块代码。
      finallyelse语句块可以同时存在。如果发生异常只执行finally语句块,否则两语句块都会执行。

    #encoding=utf-8

    import sys

    try:

      s = raw_input('Enter something --> ')

    except KeyboardInterrupt:

      print ' Why did you do an Ctrl+c on me?' #ctrl+c

      sys.exit() # exit the program

    except:

      print ' Some error/exception occurred.' #ctrl+z 报错

    else:

      print "no exception occur!"

    finally:

    print "finally is executed!"

     

     

    Finally 要放在 else后面,否则会报语法错误。

    1. 自定义异常

    #coding=utf-8

    class Networkerror(RuntimeError):

      # 重写默认的__init__()方法,

      # 抛出特定的异常信息

      def __init__(self, value):

        self.value = value

     

    #触发自定义的异常

    try:

      raise Networkerror("Bad hostname")

    except Networkerror, e:

    print "My exception occurred, value:", e.value

     

     

     

    1. 通过创建一个新的异常类,程序可以创建它们自己特定的异常。自定义异常都需
      要继承异常基类( Exception类),当然也可以继承具体的异常类(比如RuntimeError),通过直接或间接的方式。

    #coding=utf-8

    class ShortInputException(Exception):

      '''A user-defined exception class.'''

      def __init__(self, length, atleast):

        Exception.__init__(self)

        self.length = length

        self.atleast = atleast

    try:

      s = raw_input('Enter something --> ')

      if len(s) < 3:

        #如果输入的内容长度小于3,触发异常

        raise ShortInputException(len(s), 3)

    except EOFError:

      print ' Why did you do an EOF on me?'

    except ShortInputException, x:

      print 'ShortInputException: The input was of length %d,

      was expecting at least %d' % (x.length, x.atleast)

    else:

    print 'No exception was raised.'

     

     

     

     

    1. 异常抛出机制:
    2. 如果在运行时发生异常,解释器会查找相应的处理语句(称为handler)
    3. 要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看
      那里能不能处理。
    4. 如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印
      出traceback以便让用户找到错误产生的原因。
    5. 注意:
      虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个
      警告,有时候它们可能是一个终止信号,比如退出循环等。
    6. with处理的对象必须有__enter__()__exit__()这两个方法。其中__enter__()方法在语句体(with语句包裹起来的代码块)执行之前进入运行,__exit__()方法在语句体执行完毕退出后运行。

    Eg:读文件

    >>> with open(r"e:\b.py") as fp:

    ...     fp.read()

       With是会自动打开和关闭文件的

     

    with是一种上下文管理协议,目的在于从流程图中把 try,except finally 关键字和资源分配释放相关代码统统去掉,简化try….except….finlally的处理流程。

     

    Eg:自定义with异常;自动打开自动关闭的原理,利用with的方法处理异常

    # encoding=utf-8

    class opened(object):

        def __init__(self, filename):

            self.handle = open(filename)

            print 'Resource: %s' % filename

        def __enter__(self):

            print '[Enter %s]: Allocate resource.' % self.handle #打开文件会返回一个句柄,handle

            return self.handle  # 可以返回不同的对象

        def __exit__(self, exc_type, exc_value, exc_trackback):

            print '[Exit %s]: Free resource.' % self.handle

            if exc_trackback is None:  # raise TypeError存在,这里以下的代码不会执行

                print '[Exit %s]: Exited without exception.' % self.handle

                self.handle.close()

            else:

                print "error occur!" #句柄泄漏

                #return True  #返回true的话,不会中断程序的执行

                return False  #会抛出异常,中断程序的执行

     

    with opened(r'e:a.py') as fp:

        for line in fp.readlines():

            print(line)

            raise TypeError  #这里有自己发起的异常,上面的exc_trackback就一定有值

    print "Dnoe"

     

     

    1. 断言

    在没完善一个程序之前,我们不知道程序在哪里会出错,与其让它运行时崩溃,不如在出现错误条件时就崩溃,这个时候我们就需要用到断言。assert断言是声明其布尔值必须为真的判断,如果发生异常就说明表达式为假。如果断言成功不采取任何措施(类似语句),否则触发AssertionError(断言错误)的异常。

    #coding=utf-8
    def add( x, y, *d) :
    result = x + y
    for i in d :
    result += i
    return result
    if __name__ == '__main__' :
    assert 10 == add(1,2,3,4)

     

    知识回顾:

    1. 拆包,一个星 *

    #coding=utf-8
    def add( x, y, *d) :
        print d

    if __name__ == '__main__' :
        add(1,2,3,4,5)

     

    1. 两个星星,操作字典

    #coding=utf-8
    def add( x, y, **d) :
        print d

    if __name__ == '__main__' :
        add(1,2,a=4,b=5)

     

     

    1. 模块

     

    a.py和b.py在同一个路径下,可以直接找到

           若是有重命名的会根据就近原则去调用,模块和变量尽量不要重名。

    关键字冲突。

            

     

    模块之间的调用:

          

          还可以调用类:

        

    也可以换一种导入方法

     

     

    也可以导入具体的方法 from a import x

     

     

     

     

    1. 命名空间

    import gloryroad  #直接引入这个命名空间到b,作为b的子空间,引用时需要加入gloryroad.* 去引用

    gloryroad:add x

    b:

     

    gloryroad.add(1,2)

     

    from gloryroad import *  #这样引用相当把b的命名空间下所有代码都引入了b,可以直接调用

    b:add x

     

    print x

    print add(1,2)

     

    1. 全局变量

    #coding=utf-8

    Money=[2000]

    def AddMoney():

        # 想改正代码就取消以下注释:

        #global Money

        Money=Money+[1]

    print Money

    AddMoney()

    print Money

     

     

    不是全局变量的话,直接append不会出错

    如果函数体内部和外部都有同一个变量,会优先使用函数内部的变量。

    #coding=utf-8
    Money=2000
    def AddMoney():
        # 想改正代码就取消以下注释:
        Money=100
        Money=Money+1
        return Money
    print Money
    print AddMoney()
    print Money

     

     

    1. reload导入

    把模块重新引入了一遍

     

    1. 局部变量和全局变量

    #encoding=utf-8

    def foo():

      print "calling foo()..."

      aStr = "bar"

      anInt = 23

      print "foo()'s globals:", globals().keys() #函数内部调用全局和局部变量是一样的

      print "foo()'s locals:", locals().keys()

     

    print "__main__'s globals:", globals().keys() #函数外部调用是不一样的

    print "__main__'s locals:", locals().keys()

    foo()

     

     

     

    1. 包:在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,这里就需要运用包的概念了。包是一个分层的文件目录结构,它定义了一个由模块及子包和子包下的子包等组成的Python的应用环境。

    包是目录,包含模块。

     

     

    保证a和b不在同一个路径下

    a的内容:

    #encoding = utf-8

    def add(a,b):

    return a+b

       b的内容:

       #conding = utf-8

    import test.a

    print test.a.add(1,2)

    __init__的内容是空的

     

    还可以再建立一级子包

    #conding = utf-8

    import test.test1.a

    print test.test1.a.add(1,2)

    调用时写到子包一级

     

    1. 调用包练习

     

     

    1. 也可以直接在__init__把函数名写进去,然后b里面调用时可以直接写到包名一级

     

     

     

  • 相关阅读:
    定义函数
    变量与常量
    字符串与格式化
    字符串与编码
    字符编码
    元组-tuple
    列表-list
    分支和循环
    润乾配置连接kingbase(金仓)数据库
    润乾报表在proxool应用下的数据源配置
  • 原文地址:https://www.cnblogs.com/qingqing-919/p/8620354.html
Copyright © 2020-2023  润新知