四.Python高阶函数和装饰器

Laozizuiku 2019-12-28

目录

  • 高阶函数
    • 数学概念
    • 内建高阶函数
    • 柯里化
    • 装饰器

01高阶函数

1.1 数学概念

y=g(f(x)),在数学和计算机科学中,高阶函数至少应当是满足下面一个条件的函数:
1)接受一个或者多个函数作为参数
2)输出一个函数
示例计数器:

def counter(base):
    def inc(step=1):
        nonlocal base
        base += step
        return base
    return inc

1.2 内建函数--高阶函数

sorte(iterable[,key][,reverse]) 排序,返回一个列表
filter(function, iterable) 过滤可迭代对象的元素,返回一个迭代器
map(function, *iterable) -->map object 对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器

1.3 柯里化Currying

柯里化:指的是将原来接受两个参数的函数变成新的接收一个参数的函数,新的函数返回一个以原有第二个参数为参数的函数
z = f(x, y)转换成z=f(x)(y)

通过嵌套函数就可以把函数转换成柯里化函数

举例

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

改变后

def add(x):
    def _add(y):
        nonlocalt x
        retrun x+y
    return _add

1.4 装饰器:

引入:
一个加法函数,想着增强它的功能,能够输出被调用过以及调用的参数信息

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

加入信息输出功能:

def add(x, y):
    print("call add, {}+{}".format(x,y))
    return x + y

上面的加法函数是完成了需求,但有以下缺点:
1)打印语句的耦合太高
2)加法函数属于业务功能,而输出信息属于非业务功能代码,不该放在业务函数加法中

如下改进:

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

def logger(fn):
    print("Begin")
    x = fn(4, 5)
    print("end")

print(logger(add))

那么做到业务功能分离,没有侵入式代码
改进

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

def logger(fn,x,y):
    print('before')
    ret = fn(x,y)
    print('after')
    return ret

但是fn的参数受限制,只能针对含有两个参数的
继续改进

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

def logger(fn,*args,**kwargs):
    print('before')
    ret = fn(*args,**kwargs)
    print('after')
    return ret

柯里化的方式

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

def logger(fn):
    def _logger(*args, **kwargs):
        print('before')
        ret = fn(*args, **kwargs)
        print('after')
        return ret
    return _logger
# 如下调用
add = logger(add)  # 因为函数调用的关系,参数add的引用用在函数内部保存
add(4, 5) # 调用的是内部保存的add引用,而非原本的add函数

Python将其改进为装饰器

def logger(fn):
    def _logger(*args, **kwargs):
        print('before')
        ret = fn(*args, **kwargs)
        print('after')
        return ret
    return _logger

@logger
def add(x,y):
    return x+y

print(add(4, 10))
  • 装饰器和高阶函数
    装饰器是高阶函数,但装饰器是对传入函数的功能装饰或者是功能增强

相关推荐