Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 691|回复: 0

python-自定义异常,with用法

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-20 05:48:38 | 显示全部楼层 |阅读模式

    抛出异常

    #coding=utf-8

     

    def  exceptionTest(num):

        if num<0:

            print "if num<0"

            raise Exception("Invalid num")

     

        else:

            print num

        if num == 0:

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

     

    print exceptionTest(-43)

     

    c:\Python27\Scripts>python task_test.py

    if num<0

    Traceback (most recent call last):

      File "task_test.py", line 14, in <module>

        print exceptionTest(-43)

      File "task_test.py", line 7, in exceptionTest

        raise Exception("Invalid num")

    Exception: Invalid num

     

     

     

    #coding=utf-8

     

    def  exceptionTest(num):

        if num<0:

            print "if num<0"

            raise Exception("Invalid num")

     

        else:

            print num

        if num == 0:

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

        return ""

     

    print exceptionTest(4)

     

     

    c:\Python27\Scripts>python task_test.py

    4

     

     

    #coding=utf-8

     

    def  exceptionTest(num):

        if num<0:

            print "if num<0"

            raise Exception("Invalid num")

     

        else:

            print num

        if num == 0:

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

        return ""

     

    print exceptionTest(0)

    c:\Python27\Scripts>python task_test.py

    0

    Traceback (most recent call last):

      File "task_test.py", line 14, in <module>

        print exceptionTest(0)

      File "task_test.py", line 11, in exceptionTest

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

    ZeroDivisionError: interger division or modulo by zero

     

     

     

    自定义异常

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

    #coding=utf-8

     

    class Neterror(RuntimeError):

        def __init__(self,value):#重写默认的__ini__()方法

            self.value=value

     

    #触发自定义的异常

    try:

        raise Neterror("Bad hostname")

    except Neterror,e:

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

     

    c:\Python27\Scripts>python task_test.py

    My exception occurred,value: Bad hostna

     

    #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 '\nWhy did you do an EOF on me?'

    except ShortInputException,x:

        print "shortInputException:The input was of length %d,\

        was excepting at least %d"%(x.length,x.atleast)

    else:

        print "No exception was raised"

    c:\Python27\Scripts>python task_test.py

    Enter something-->234s

    No exception was raised

     

    c:\Python27\Scripts>python task_test.py

    Enter something-->3e3

    No exception was raised

     

    c:\Python27\Scripts>python task_test.py

    Enter something-->w

    shortInputException:The input was of length 1,    was excepting at least 3

     

    c:\Python27\Scripts>python task_test.py

    Enter something-->

    shortInputException:The input was of length 0,    was excepting at least 3

     

    异常抛出机制:

    1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler)。

    2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看 那里能不能处理。

    3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。

    注意:

    虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等

     

    标准异常说明

    上面列举的标准异常集,所有的异常都是内建的.。所以它们在脚本启动前或在互交命令行提示符出现时已经是可用的了。

    所有的标准/内建异常都是从根异常派生的。目前,有3 个直接从BaseException 派生的异常子类:SystemExit,KeyboardInterrupt 和Exception。其他的所有的内建异常都是Exception 的子类。

    Python2.5开始,所有的异常的都是BaseException 的子类。

     

     

    With介绍:

    with是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关

    代码统统去掉,简化try….except….finlally的处理流程。with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。其中__enter__()方法在语句体(with语句包裹起来的代码块)执行之前进入运行,__exit__()方法在语句体执行完毕退出后运行。

    with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

     

     

    With语句的基本语法格式如下

    with expression [as target]:

    with_body

    参数说明:

    expression:是一个需要执行的表达式;

    target:是一个变量或者元组,存储的是expression表达式执行返回的结果, 可选参数。

    #coding=utf-8

    with open("d:\\a.txt",'r') as fp:

        print fp.read()

       

    c:\Python27\Scripts>python task_test.py

    sdfsdfsdfsdf1

     

    with语句的工作原理:

    紧跟with后面的语句会被求值,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as关键字后面的变量,当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

     

     

    从前面我们知道,with语句最关键的地方在于被求值对象必须有__enter__()和__exit__()这两个方法,那我们就可以通过自己实现这两方法来自定义with语句处理异常。

     

    #coding=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

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

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

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

            if exc_trackback is None:

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

                self.handle.close()

            else:

                print "[Exit %s]: Exited with exception raised." %self.handle

            return False#可以省略,缺省的None也是被看作是False

     

    with opened("d:\\a.txt") as fp:

        for line in fp.readlines():

            print line

    c:\Python27\Scripts>python task_test.py

    Resource:d:\a.txt

    [Enter<open file 'd:\\a.txt', mode 'r' at 0x0000000002BC7150>]:Allocate resource.

    sdfsdfsdfsdf1

    [Exit<open file 'd:\\a.txt', mode 'r' at 0x0000000002BC7150>]:Free resource.

    [Exit<open file 'd:\\a.txt', mode 'r' at 0x0000000002BC7150>]:Exited without exception.

     

    示例代码说明:

    opened中的__enter__() 返回的是自身的引用,这个引用可以赋值给 as 子句中的fp变量;返回值的类型可以根据实际需要设置为不同的类型,不必是上下文管理器对象本身。

    __exit__() 方法中对变量exc_trackback进行检测,如果不为 None,表示发生了异常,返回 False 表示需要由外部代码逻辑对异常进行处理;如果没有发生异常,缺省的返回值为 None,在布尔环境中也是被看做 False,但是由于没有异常发生,__exit__() 的三个参数都为 None,上下文管理代码可以检测这种情况,做正常处理。__exit__()方法的3个参数,分别代表异常的类型、值、以及堆栈信息。

     

    命名空间

    Random是命名空间

    导入ramdom命名空间里的randint函数

    #encoding=utf-8

     

    >>> from random import randint

    >>> print randint(10,20)

    18

     

    一起引入两个

    >>> from random import randint,choice

    >>> print randint(10,20)

    11

    >>> print choice([1,2,3,4])

    3

    >>> 

     

    直接用*,引入所有函数,但是坏处是如果本地有一个自定义的函数与命名空间里的函数同名,命名空间里的该函数会被覆盖

     

    >>> from random import *

    >>> print randint(10,20)

    14

    >>> print choice([1,2,3,4])

    4

    >>> 

     

    覆盖例子:

    #coding=utf-8

     

    from random import *

     

    def randint():

        return 1

     

    print randint(1,20)

     

    c:\Python27\Scripts>python task_test.py

    Traceback (most recent call last):

      File "task_test.py", line 8, in <module>

        print randint(1,20)

    TypeError: randint() takes no arguments (2 given)

     

    练习:
    生成一个模块a.py,里面定义一个变量c=100,定义一个函数def add(a,b) 在b.py中通过import a 和from a import *的两种方法来引入使用c变量和add函数

    a.py:

    import b

    c=100

    def add(a,b):

        return a+b

     

    b.py:

    import a

     

    print a.c

    print a.add(1,2)

     

    c:\Python27\Scripts>python task_test.py

    100

    3

     

     

    b.py:

    #coding=utf-8

     

    from a import *

     

    print c

    print add(1,2)

    c:\Python27\Scripts>python task_test.py

    100

    3

     

    如果一个py文件中有if __name__ == '__main__':,只有在运行该文件时才会执行,该文件在别文件中引用,不会被执行

    a.py:

    #encoding=utf-8

     

    c=100

     

    def add(a,b):

        return a+b

     

    if __name__=='__main__':

        print c

        print add(10,20)

     

    c:\Python27\Scripts>python a.py

    100

    30

     

    b.py:

    #coding=utf-8

     

    from a import *

     

    print c+add(1,2)

     

    c:\Python27\Scripts>python task_test.py

    103

    没有显示a.pyif __name__==’__main__’:下边的代码

     

    在b.py中import a, 则a.py中的代码会都执行一遍

     

    import a

    reload(a)

     

    reload后会再执行一遍a中的代码

     

    如果import a两次,则只执行一遍a中的代码

     

     

    Import a

    Import a

     

     

    a.py:

    #encoding=utf-8

     

    c=100

     

    def add(a,b):

        return a+b

     

     

    print "import a, codes in a will run"

     

    if __name__=='__main__':

        print c

    print add(10,20)

     

    b.py:

     

    #coding=utf-8

     

    from a import *

     

    c:\Python27\Scripts>python task_test.py

    import a, codes in a will run

     

    b.py:import 两遍

    #coding=utf-8

     

    from a import *

    from a import *

    c:\Python27\Scripts>python task_test.py

    import a, codes in a will run

    只执行一次

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 16:49 , Processed in 0.061163 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表