zoukankan      html  css  js  c++  java
  • 笨办法学Python记录--习题37 异常,lambda,yield,转义序列

    习题中提到了raise,查了下,顺便所有异常类关键字罗列如下文章中:                                  

    为什么使用异常

    错误处理、事件通知、特殊情况处理、退出时的行为、不正常的程序流程。

    简单的示例

    在没有任何定义x变量的时候:

    print x
    print 1

    将会抛出NameError异常:

    NameError: name 'x' is not defined

    而且1并不会被输出,也就是说程序将被中断。如果讲代码修改如下:

    try:
    print x
    exceptNameError:
    print "Something is wrong!"
    print 1

    得到的输出将是:

    Something is wrong!
    1

    可见,我们定义的except会“抓住”NameError类型的语句,并且执行相应的处理代码,而且程序不会被中断。

    使用raise

    我们可以自己触发异常,例如:

    raise IndexError

    Python会返回:

    Traceback (most recent call last):
    File "d:我的文档桌面 odoexep.py", line 1, in <module>
    raise IndexError
    IndexError

    自定义的异常

    下面定义了一个MyException类,它继承自Python内置的Exception类。

    class MyException(Exception):pass
    try:
    #some code here
    raise MyException
    except MyException:
    print "MyException encoutered"

    结果为:

    MyException encoutered

    可以在一个except内捕获多个异常:

    except (AttributeError, TypeError, SyntaxError):
      

    捕获所有异常

    只要在except后面不加任何异常类型,这个except块就可以捕获所有的异常。

    except:

    捕获异常的继承关系

    当我们except Super的时候,同样会捕获到raise Sub的异常。

    finally

    无论try块是否抛出异常,永远执行的代码。通常用来执行关闭文件,断开服务器连接的功能等等。

    class MyException(Exception):pass
    try:
    #some code here
    raise MyException
    except MyException:
    print "MyException encoutered"
    finally:
    print "Arrive finally"

    结果:

    MyException encoutered
    Arrive finally

    try、except、else

    可以在try块里加入else块,代码块将在没有异常被抛出的时候执行:

    try:
    print "normal code here"
    except MyException:
    print "MyException encoutered"
    else:
    print "No exception"

    finally:
    print "Arrive finally"

    结果为:

    normal code here
    No exception
    Arrive finally

    raise异常、同时添加数据

    raise异常的同时,我们可以添加一些额外的数据,就像下面的例子一样:

    class MyException(Exception):pass
    try:
    raise MyException,", and some additional data"
    except MyException,data:
    print "MyException encoutered"
    print data

    断言assert

    断言是指期望指定的条件满足,如果不满足则抛出AssertionError异常。例如:

    def positive(x):
    assert x > 0
    print "x"
    positive(1)
    positive(0)

    positive(0)一句将会抛出一个异常。

    with/as

    with/as语句主要是为了代替try/finally语句、通常用来做一些善后工作或者是清理现场的工作。

    with open('test.txt') as myfile:
    for line in myfile:
    #code here
    #code here

    当with代码块结束之后,文件将会自动关闭。这是因为返回的对象支持context management protocol。原书598页有关于该协议的讨论,例如如何自定义一个支持该协议、从而支持with语句的类。

    yield:貌似是个迭代常量的标记,详细参考“文章”里的一篇。

    lambda函数介绍

    在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda?

      下面就上面的问题进行一下解答。

      1、lambda是什么?

        看个例子:     

    1 g = lambda x:x+1

      看一下执行的结果: 

      g(1)

      >>>2

      g(2)

      >>>3

      当然,你也可以这样使用:

      lambda x:x+1(1)

      >>>2   

      可以这样认为,lambda作为一个表达式,定义了一个匿名函数,上例的代码x为入口参数,x+1为函数体,用函数来表示为:

    1 def g(x):
    2 return x+1

      非常容易理解,在这里lambda简化了函数定义的书写形式。是代码更为简洁,但是使用函数的定义方式更为直观,易理解。

      Python中,也有几个定义好的全局函数方便使用的,filter, map, reduce  

    复制代码
    >>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
    >>>
    >>> print filter(lambda x: x % 3 == 0, foo)
    [18, 9, 24, 12, 27]
    >>>
    >>> print map(lambda x: x * 2 + 10, foo)
    [14, 46, 28, 54, 44, 58, 26, 34, 64]
    >>>
    >>> print reduce(lambda x, y: x + y, foo)
    139
    复制代码

      上面例子中的map的作用,非常简单清晰。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。

      比如上面map的例子,可以写成:

        print [x * 2 + 10 for x in foo]

      非常的简洁,易懂。

      filter的例子可以写成:

        print [x for x in foo if x % 3 == 0]

      同样也是比lambda的方式更容易理解。


      上面简要介绍了什么是lambda,下面介绍为什么使用lambda,看一个例子(来自apihelper.py):  

    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)

      在Visual Basic,你很有可能要创建一个函数,接受一个字符串参数和一个 collapse 参数,并使用 if 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在 Python 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的 lambda 函数提供确切的 (唯一的) 你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 (哦,想到那些参数就头昏) 的错误。

      通过此例子,我们发现,lambda的使用大量简化了代码,使代码简练清晰。但是值得注意的是,这会在一定程度上降低代码的可读性。如果不是非常熟悉python的人或许会对此感到不可理解。


      lambda 定义了一个匿名函数

      lambda 并不会带来程序运行效率的提高,只会使代码更简洁。

      如果可以使用for...in...if来完成的,坚决不用lambda。

      如果使用lambda,lambda内不要包含循环,如果有,我宁愿定义函数来完成,使代码获得可重用性和更好的可读性。


      总结:lambda 是为了减少单行函数的定义而存在的。

     字符串转义序列:




    f 匹配一个换页符。等价于x0c和cL。
    v 匹配一个垂直制表符。等价于x0b和cK。
    转义字符描述
    (在行尾时) 续行符
    \ 反斜杠符号
    单引号
    双引号
    a 响铃
     退格(Backspace)
    e 转义
    00
    换行
    v 纵向制表符
    横向制表符
    回车
    f 换页
    oyy 八进制数yy代表的字符,例如:o12代表换行
    xyy 十进制数yy代表的字符,例如:x0a代表换行
    other 其它的字符以普通格式输出

         

    Python格式化字符串的替代符以及含义

        符   号     说     明
          %c  格式化字符及其ASCII码
          %s  格式化字符串
          %d  格式化整数
          %u  格式化无符号整型
          %o  格式化无符号八进制数
          %x  格式化无符号十六进制数
          %X  格式化无符号十六进制数(大写)
          %f  格式化浮点数字,可指定小数点后的精度
          %e  用科学计数法格式化浮点数
          %E  作用同%e,用科学计数法格式化浮点数
          %g  根据值的大小决定使用%f活%e
          %G  作用同%g,根据值的大小决定使用%f活%e
          %p  用十六进制数格式化变量的地址

    Python语言中的@符号有比较特殊的含义,而且是一种比较稀有的特性,初学者往往不容易理解,这里就其做一些解释。 首先看一段代码:

    ?Download download.txt
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    def minus(f):
        print 'minus'
        f()
     
    def plus(f):
        print 'plus'
        f()
     
    def test(a):
        if a > 3 : return plus
        else : return minus
     
    @test(5)
    def xxx():
        print 'ok'

    解释器首先会解释@符号后面的代码,如果如上面的代码类似,那么test(5)将被执行,因为test参数5大于3,所以会返回一个函数指针plus(可以用C的这个名字来理解),plus将下一行的函数指针xxx当作参数传入,直到执行完成。最后结果将输出‘plus’和‘ok’。 有时候可能是下面这种形式:

    ?Download download.txt
     
    1
    2
    3
    4
    5
    6
    7
    
    def minus(f):
        print 'minus'
        f()
     
    @minus
    def xxx():
        print 'ok'

    minus因为本身已经是一个函数指针,所以会直接以xxx作为参数传入,结果会输出‘minus’和‘ok’。

  • 相关阅读:
    【百度地图API】让用户选择起点和终点的驾车导航
    JS解决通过按钮切换图片的问题
    JavaScript (JS)基础:DOM 浅析 (含数组Array、字符串String基本方法解析)
    JavaScript (JS)基础:ECMAScript 浅析 (含Math基本方法解析)
    感谢Sylvia的技术支持
    0904 存储过程、触发器、事务、视图、生成脚本
    0903 连接查询
    0901 子查询
    0831 模糊查询,排序查询,聚合函数,时间日期函数,数学函数,字符串函数
    0829 数据库的增删改查
  • 原文地址:https://www.cnblogs.com/ianthe/p/3674191.html
Copyright © 2011-2022 走看看