[Python学习路线]--Python基础no.09

1. 闭包

形式:函数作为返回值,高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

def calc_sum(lst):
    def lazy_sum():
        return sum(lst)
    return lazy_sum

f = calc_sum() //不会调用
f()

这里的calc_sum可以进行字面理解为“懒求和”
当函数f定义好了以后,实际上是定义了一个函数的实体。只有在f()进行调用以后才进行了函数求和的功能。

闭包中有局部变量。

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()

上述中的程序返回看似返回的结果是1, 4, 9。
而实际结果全部都为16。
这从闭包的特性上也可以理解。我们定义了一个函数的实体,在其f1(),f2(), f3()调用以后才进行了输出。这里他们都是单独的函数实体,内部的值互不影响。

2. 匿名函数(lambda)

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
例如我们使用一行代码就能打印出来1,20中所有的奇数。

print(list(filter(lambda x : x % 2 == 1, range(1, 20))))

找出一组数据中的非空数据。

print filter(lambda s: s and len(s.strip()) > 0, ['test', None, '', 'str', '  ', 'END'])

由上述的例子可以看出lambda极大的减少了代码量。

3. 装饰器(decorator)

Python的decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

import time

def performance(f):
    def log_time(x):
        t1= time.time()
        res = f(x)
        t2=time.time()
        print 'call %s() in %fs' % (f.__name__, (t2 - t1))
        return res
    return log_time   

@performance
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)
call factorial() in 0.002492s
3628800

@performance在python中就是调用这个装饰器的关键字。在Java中也由类似的操作,Java中称之为注解。
当然这种高阶函数中也可以传入参数,当我们在做不通的装饰器时,返回不同的功能,最常用的就是各种loggerutl了。

import time

def performance(unit):
    def performace_docorator(f):
        def log_time(*args, **kwargs):
            start_time = time.time()
            res = f(*args, **kwargs)
            end_time = time.time()
            print("call %s() in %f%s" % (f.__name__, end_time - start_time, unit))
            return res
        return log_time
    return performace_docorator
        

@performance('ms')
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)
call factorial() in 0.002869ms
3628800

4.偏函数

当一个函数有很多参数时,调用者就需要提供多个参数。如果减少参数个数,就可以简化调用者的负担。
比如,int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换,但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做 N 进制的转换:
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

你可能感兴趣的:([Python学习路线]--Python基础no.09)