python 入门笔记(四)

来源:互联网 发布:棉花数据库 编辑:程序博客网 时间:2024/04/30 05:57

原创作品 转载请注明出http://blog.csdn.net/always2015/article/details/49454363

一、函数对象

1、lambda函数
ambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的

func = lambda x,y: x + yprint func(3,4)

lambda生成一个函数对象。该函数参数为x,y,返回值为x+y。函数对象赋给func。func的调用与正常函数无异,其实他就类似于下面这个函数:

def func(x,y):    return (x+y)

2、函数作为参数传递
函数可以作为一个对象,进行参数传递。函数名即该对象。例如:

def test(f, a, b):    print 'test'    print f(a, b)test(func, 3, 5)

test函数的第一个参数f就是一个函数对象。将func传递给f,test中的f()就拥有了func()的功能.
我们因此可以提高程序的灵活性。可以使用上面的test函数,带入不同的函数参数。比如:

test((lambda x,y: x**2 + y), 6, 9)

3、map函数

map()是Python的内置函数。它的第一个参数是一个函数对象

re = map((lambda x: x+3),[1,3,5,6])

map()有两个参数,一个是lambda所定义的函数对象,一个是包含有多个元素的表。map()的功能是将函数对象依次作用于表的每一个元素,每次作用的结果储存于返回的表re中。map通过读入的函数(这里是lambda函数)来操作数据(这里“数据”是表中的每一个元素,“操作”是对每个数据加3)。在Python 3.X中,map()的返回值是一个循环对象。可以利用list()函数,将该循环对象转换成表。
如果作为参数的函数对象有多个参数,可使用下面的方式,向map()传递函数参数的多个参数:

re = map((lambda x,y: x+y),[1,2,3],[6,7,9])#map()将每次从两个表中分别取出一个元素,带入lambda所定义的函数。

4、fileter函数

filter函数的第一个参数也是一个函数对象。它也是将作为参数的函数对象作用于多个元素。如果函数对象返回的是True,则该次的元素被储存于返回的表中。 filter通过读入的函数来筛选数据。同样,在Python 3.X中,filter返回的不是表,而是循环对象。

filter函数的使用如下例:

>>> def func(a):...     if a>100:...             return True...     else:...             return False... >>> print filter(func,[10,56,101,500])[101, 500]

5、reduce函数

reduce函数的第一个参数也是函数,但有一个要求,就是这个函数自身能接收两个参数。reduce可以累进地将函数作用于各个参数。如下例:

>>> print reduce((lambda x,y:x+y),[1,2,5,7,9])24

reduce的第一个参数是lambda函数,它接收两个参数x,y, 返回x+y。

reduce将表中的前两个元素(1和2)传递给lambda函数,得到3。该返回值(3)将作为lambda函数的第一个参数,而表中的下一个元素(5)作为lambda函数的第二个参数,进行下一次的对lambda函数的调用,得到8。依次调用lambda函数,每次lambda函数的第一个参数是上一次运算结果,而第二个参数为表中的下一个元素,直到表中没有剩余元素。

上面例子,相当于(((1+2)+5)+7)+9

注意: reduce()函数在3.0里面不能直接用的,它被定义在了functools包里面,需要引入包。

二、错误处理

1、异常处理

在项目开发中,异常处理是不可或缺的。异常处理帮助人们debug,通过更加丰富的信息,让人们更容易找到bug的所在。异常处理还可以提高程序的容错性。

我们之前在讲循环对象的时候,曾提到一个StopIteration的异常,该异常是在循环对象穷尽所有元素时的报错。

我们以它为例,来说明基本的异常处理。

一个包含异常的程序:

re = iter(range(5))for i in range(100):    print re.next()

首先,我们定义了一个循环对象re,该循环对象将进行5次循环,每次使用序列的一个元素。

在随后的for循环中,我们手工调用next()函数。当循环进行到第6次的时候,re.next()不会再返回元素,而是抛出(raise)StopIteration的异常。整个程序将会中断。

我们可以修改以上异常程序,直到完美的没有bug。但另一方面,如果我们在写程序的时候,知道这里可能犯错以及可能的犯错类型,我们可以针对该异常类型定义好”应急预案“。

>>> try:...     for i in range(100):...             print re.next()... except StopIteration:...     print "here is end ",i... 01234here is end  5

在try程序段中,我们放入容易犯错的部分。我们可以跟上except,来说明如果在try部分的语句发生StopIteration时,程序该做的事情。如果没有发生异常,则except部分被跳过。

随后,程序将继续运行,而不是彻底中断

完整的语法结构如下:

try:    ...except exception1:    ...except exception2:    ...except:    ...else:    ...finally:    ...

如果try中有异常发生时,将执行异常的归属,执行except。异常层层比较,看是否是exception1, exception2…,直到找到其归属,执行相应的except中的语句。如果except后面没有任何参数,那么表示所有的exception都交给这段程序处理。比如:

>>> try:...     print(a*2)... except TypeError:...     print("TypeError")... except :...     print ("Not type Error & Error noted")... Not type Error & Error noted

由于a没有定义,所以是NameError。异常最终被except:部分的程序捕捉。

如果无法将异常交给合适的对象,异常将继续向上层抛出,直到被捕捉或者造成主程序报错。比如下面的程序:

>>> def test_func():...     try:...             m=1/0...     except NameError:...             print("catch NameError in the sub-function")... >>> try:...     test_func()... except ZeroDivisionError:...     print("catch error in the main program")... catch error in the main program>>> 

子程序的try…except…结构无法处理相应的除以0的错误,所以错误被抛给上层的主程序。

如果try中没有异常,那么except部分将跳过,执行else中的语句。

finally是无论是否有异常,最后都要做的一些事情。

流程如下:

  • try->异常->except->finally
  • try->无异常->else->finally
0 0