继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【九月打卡】第9天 Python的函数式编程(下)

小白兔1215
关注TA
已关注
手记 55
粉丝 3
获赞 2

课程内容

  • 返回函数
  • 闭包
  • 匿名函数
  • 无参的decorator
  • 有参的decorator
  • 偏函数

学习收获

返回函数

在函数内部,是可以定义子函数的。返回函数时,不能带小括号。注意变量的作用域。

    
def calc_prod(list_):
    def prod():
        p = 1
        for i in list_:
            p = p * i
        return p
        
    return prod
    
p = calc_prod([1,2,3]);

print(p())

# 示例二

def g():
    print('g()...')

def f():
    print('f()...')
    return g

闭包

像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。

闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。返回函数不要引用任何循环变量,或者后续会发生变化的变量。

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

print(f1(),f2(),f3()) # 都是9,并不是 1,4,9

以上代码进行优化

def count():
    fs = []
    for i in range(1, 4):
        def f(x=i):     # i的值通过默认参数传入j,没有形成闭包
             return x*x   # i销毁
        fs.append(f)  
    return fs  
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())

匿名函数

有些时候,我们不需要显式地定义函数,直接传入匿名函数更方便。

匿名函数使用lambda定义:lambda x: x * x,就可以完成原来显式定义的f(x)函数的功能,冒号前面的x表示匿名函数的参数,后面的是一个表达式,匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。

l = sorted(['about', 'bob', 'Credit', 'Zoo'],key=lambda i:i[0].lower())
print(l)

无参数的decorator

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

使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。

要让函数自适应任何参数定义的函数,可以利用Python的 args 和 *kwargs,保证任意个数的参数总是能正常调用。

import time
import functools


def performance(func):
    def print_time(*args, **kwargs):
        t1 = time.time()
        r = func(*args, **kwargs)
        t2 = time.time()
        print('call print_time use time:{}'.format(t2 - t1))
        return r
    return print_time


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


print(result(10))

有参数的decorator

def log(f):
    def fn(x):
        print('call ' + f.__name__ + '()...')
        return f(x)
    return fn
	
@log('DEBUG')
def my_func():
    pass
	
# 把上面的定义翻译成高阶函数的调用,就是:
my_func = log('DEBUG')(my_func)

import time

def performance(unit):
    def perf_decorator(f):
        def fn(*args, **kw):
            t1 = time.time()
            r = f(*args, **kw)
            t2 = time.time()
            t = (t2 - t1) * 1000 if unit == 'ms' else (t2 - t1)
            print('call {}() in {}{}'.format(f.__name__, t, unit))
            return r
        return fn
    return perf_decorator
    
@performance('ms')
def fantorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
    
print(fantorial(6))

偏函数

当一个函数有很多参数时,调用者就需要提供多个参数。如果减少参数个数,就可以简化调用者的负担。

偏函数指的就是“创建一个调用另外一个部分参数或变量已经预置的函数”的函数的用法

functools.partial就是帮助我们创建一个偏函数的,functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。

import functools
sorted_ignore_case = functools.partial(sorted,key=lambda i:i[0].lower())

l = sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])
print(l)

打卡截图

vjqlWV.md.png

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP