函数式编程

后面的闭包和装饰器很重要,参数可以是函数,把函数传进去参与运算。

过程是一个没有返回值的函数,函数本身也是一个对象,因此可以赋值给引用;

一个模块中函数不可重名,因此不支持重载,因为python是以函数名来识别调用的哪一个;

模块中函数的定义是自上而下的;

可以多个返回值,看作是一个元组;也可以分开多个变量接受返回值;

def p():    return 1,2,3a=p()print aa,b,c=p()print a,b,c

函数的属性

文档属性:__doc__

可以对函数直接传东西进去;

函数参数

位置参数,必须传入;默认参数,可传入,在函数定义时用=..输入默认值,在外界不传入时,使用默认值;可变长度参数,*args元组类型的可变参数,**kwargs字典类型的可变参数;

这几种不同的参数类型可以单个使用,也可以一同使用。

#       位置参数,默认参数,可变参数(元组,字典)def func(name,count=1,*args,**kwargs):    print name    print count    print args    print kwargs# 如果传入为确认名字值,和函数一样,则对号入座func(count=1,name=2)func("python",12,13,14,15,code=12)# 对应输出为     python   12   (13, 14, 15)   {'code': 12}   func("python",*(12,13,14,15),**{'code'=12})#这里后面的可变参数会有一部分当作默认参数传入,即12当作默认传入,后面才是可变参数

函数的参数,只有满足前面的参数,才会依次使用,位置参数一定要传入。

Lambda

本身也是一个函数,是一个匿名函数,只能是一行

#表示传入x,返回x+1a = lambda x:x+1print a(1)

变量的作用域

x = 1def func():    #这里的global作用是声明这个x是外部的x    global x    x+=1    print xfunc()

函数的闭包:

def f1(x):    def f2(y):        return x*y    return f2#这里把函数f1的值传入后,给f2,相当于在操作F2之前,注入了一个预先的值,输入了xf2 = f1(10)#输入了yprint f2(10)

装饰器

@start('shizhen')

这个就是装饰器,用在函数的上面

函数的调用可以是一层一层的,外面传入参数,内层的可以使用;

def start(name):    def wrapper(f):        def wrapper1():            print "start by "+name            f()        return wrapper1    return wrapper#装饰器要放在函数的上面@start('shizhen')def f():    print "function"#这里运行时运行@的这个函数start,会把f这个函数在第二层的时候传进去执行,特点是参数可以是函数, 不再只是单独的对象,而是函数。start的第一层如果无参数‘shizhen’的话,则直接传入f函数。f()

练习题:

1.实现一个函数max,接受任意个整数的参数,返回其中的最大值

def max(*args):    length = len(args)    if length == 0:        print "empty"    else:        result = args[0]        for i in range(0,length):            if result < args[i]:                result = args[i]        print " max is "  + str(result)max(1,2,3,5,2,3,7,8,2,1,10)

2.实现一个带参数的装饰器@callfunction(caller name), 传入的参数是调用者的名字,在调用函数之前,先打印一句 "The caller is [caller name]"的log

def callfunction(name):    def wrapper(f):        #这一层的作用是传入f的传入参数,这里是空,可用*args(可变参数)作为通用的参数        def wrapper1():            print "the caller is " + name            f()        return wrapper1    return wrapper@callfunction("shizhen")def f():    print "shizhen is so cool"f()

装饰器需要一层一层的先把参数和函数全都传入后,在内部自建一层才能把前面传入的所有进行运算。

callfunction('shizhen')(f)()

3.实现一个装饰器@timeit, 这个装饰器的作用是当函数执行完毕以后,打印出来具体使用的时间

#第一层传入func函数def timeit(f):    #第二层传入func函数的输入参数    def wrapper(*args,**kwargs):        print (time.strftime("%H:%M:%S"))        f(*args,**kwargs)        print (time.strftime("%H:%M:%S"))    return wrapper@timeitdef func(*args):    for i in range(0,len(args)):        if args[i] > 10:            print "find:" + str(args[i])            time.sleep(1)func(1,23,12,31,2,1,23,12,31,23,1,23,1,23,4,3,42,3,42,34,111)

函数式编程时,参数的传入是分开的,一个整体一个整体的传,先传函数本体,再传函数的输入参数

timeit(f)(*agrs)

*agrs也就是可以是多个参数,也可以是没有参数。

*args,**kwargs。用这两个作为参数的函数接受参数是非常安全的。

也就是一层一层的把东西传入进去,装饰器参数+函数+函数参数(*args,**kwargs这个很安全)。。