Python 4th Day

高阶函数

函数可以赋值给变量

>>> f = abs
>>> f(-10)
10

即变量可以指向函数,如果一个变量指向了一个函数,那么可以通过该变量调用这个函数。函数名其实就是指向函数的变量

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

函数作为返回值

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

一个求和函数,将结果返回:

def calc_sum(*args):
    ax = 0
    for i in args:
        ax = ax + i
    return ax

如果需要返回求和函数而不是结果:

def lazy_sum(*args):
    def sum():
        ax = 0
        for i in args:
            ax = ax + i
        return ax
    return sum

当我们调用 lazy_sum 函数时,返回的并不是求和结果,而是求和函数,

>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f() # 调用 lazy_sum 函数,f 接受返回的 sum 函数,以及传入 lazy_sum 函数的参数
25

当再调用 f 时,才返回求和结果。

我们在函数 lazy_sum 中又定义了函数 sum,并且,内部函数 sum 可以引用外部函数 lazy_sum 的参数和局部变量,当 lazy_sum 返回函数 sum 时,相关参数和变量都保存在返回的函数中,这种结构成为 "闭包(Closure)"

闭包

上面的例子中,返回的 sum 函数在内部引用了 lazy_sum 函数的参数,所以,当一个函数返回了一个函数后,其内部的局部变量和参数还被新函数引用。

装饰器

装饰器用来在不改变函数的情况下,动态增加函数的功能。本质上装饰器就是一个返回函数的高阶函数。

装饰器的外层函数接收一个函数作为参数,并返回一个函数。

当使用 @outer 装饰 f1 函数时,相当于执行了 f1 = outer(f1), 即自动执行 outer 函数并将 f1 函数当做参数传给 outer 函数,然后将 outer 函数的返回值重新赋值给 f1, 这样就增加了原有 f1 函数的功能。

def outer(func):
    def inner(*args, **kwargs):
        print('before')
        r = func(*args, **kwargs)
        print('after')
        return r
    return inner
@outer
def f1(arg1, arg2):
    print('f1')
    return "return value"

调用 f1 函数,

f1('aaa', 'bbb')

返回,

before
f1
after

原有 f1 函数 print('f1') 功能实现之外还额外打印了装饰器内层函数中增加的 'before' 和 'after', 装饰器的本质是将同名的 f1 变量指向了新的函数。 

一些内置函数的用法

生成 6 位包括字母和数字的随机密码

import random

li = []

# 生成随机数[0-5]
for i in range(6):
    # 当随机数等于2或者4时
    if i ==2 or i == 4:
        # 得到一个0-9的随机数
        num = random.randrange(0, 10)
        # 把这个数加进 list
        li.append(str(num))
    else:
        # 否则生成65-90的随机数
        temp = random.randrange(65, 91)
        # 利用 chr 函数从 ascii 表中得到对应的字母
        c = chr(temp)
        # 把这个字母加进 list
        li.append(c)

result = ''.join(li)
  • isinstance
  • s = [11,11,11]
    r = isinstance(s, list)
    print(r)

    如果 s 是 list 则返回 true

  • filter
  • # 函数 f2 如果参数大于 22 则返回 true
    def f2(a):
        if a > 22:
            return True
    
    li = [11, 22, 33, 44, 55]
    
    # filter 函数遍历 li, 迭代每一个元素作为参数传入 f2 函数, 如果 f2 函数返回真则将元素添加进 filter 函数的返回值
    ret = filter(f2, li)
    # filter 返回 filter 类型, 需要转换类型
    print(list(ret))
  • map
  • li = [11, 22, 33, 44, 55]
    
    result = map(lambda a: a + 100, li)
    print(list(result))

    map 函数将 li 中每一个元素作为参数传入另一个函数,并将执行函数的返回值添加到结果中。

 

posted @ 2016-06-03 17:10  garyyang  阅读(149)  评论(0)    收藏  举报