1.高阶函数
- 1.1高阶的理解
在学习前错误认为函数的嵌套没有必要,正常调用函数就可以了。通过学习就知道以前的想法多么可笑,这是没有系统学习,没参加过大型项目导致的。这节课主要讲的就是嵌套函数的作用。 - 1.2高阶函数的条件
下面两个条件满足一条就是高阶函数。- 传入参数是函数对象
- 返回值是函数对象
lst = [1,2,3,4,5,6,7,8,9]
def f(fn,lst):
'''
按照函数功能来筛选数字序列
:param fn: 功能函数,作为筛选条件
:param lst: 需要筛选的序列
:return: 筛选后的新序列
'''
result = []
for i in lst:
if fn(i):
result.append(i)
return result
def fn1(n):
return n%2==0
def fn2(n):
return n%3==0
def fn3(n):
return n > 5
print(f(fn1,lst))
print(f(fn2,lst))
print(f(fn3,lst))
'''
输出结果为:
[2, 4, 6, 8]
[3, 6, 9]
[6, 7, 8, 9]
'''
- 1.3无名函数lamdba
所有简单的函数可以用关键字lamdba建立一个临时函数来处理- 语法
lamdba 参数:返回值表达式
- 使用条件:必须是一个表达式就能表达返回值的简单函数,只调用一次不需要在其他地方使用的函数。
- 语法
lst = [1,2,3,4,5,6,7,8,9]
def fn1(n):
return n%2==0
print(list(filter(fn1,lst)))#filter()函数就是我们前面写的筛选序列的函数。结果为[2, 4, 6, 8]
result = list(filter(lambda x:x%2==0,lst))
print(result)#结果同样为[2, 4, 6, 8]
f = lambda x:x%2 != 0
print (f,type(f))#<function <lambda> at 0x0066DA48> <class 'function'>
#变量f是个函数,名字部分由lambda代替,也就说无名。
2.闭包
-
2.1闭包的条件
- 返回值是一个函数(这个函数作用域记作第二层)
- 第一层函数中定义一个变量,这个变量要被第二层函数使用
2.2闭包的作用
闭包主要在联合开发中使用,为了减少因为命名重复的问题引入。一般优秀的程序员会把自己的程序都写成类或者函数,在全局域中只调用这些函数或实例化这些类,这也是为了避免出现因为重命名而引发冲突。
def fn():
i = 10
def fn1():
return i//5
return fn1
print(fn()())#结果为2
print(i)#NameError: name 'i' is not defined
#这个fn()函数就是个闭包
3.装饰器
- 3.1 装饰器的引入
需要为已经写好的函数增加功能,可以通过修改函数代码来实现,但是这样会带来以下三个问题。- 如果函数比较多,改起来很麻烦。
- 不方便后期的维护
- 违反了开闭原则(ocp)。程序的设计,要求开发对程序的扩展,要关闭对程序的修改。我理解就是扩展不能通过修改代码的方式,这样就不会让原函数产生新的bug,可以避免修改好的bug反复出现的情况。
- 3.2 装饰器的使用
装饰器就是能够扩展原函数功能的高阶函数。这样既可以处理大量函数,也方便后期维护,同时遵循了开闭原则。
def decorator(old):
def new_fn(*args,**kwargs):
print('我在运行中')
r = old(*args,**kwargs)
return r
return new_fn
@decorator
def add(a,b):
return a+b
@decorator
def mul(a,b):
return a*b
@decorator
def fn():
print('我爱学习python!!!')
fn()
print(add(1,101))
print(mul(6,7))
'''
运行结果为:
我在运行中
我爱学习python!!!
我在运行中
102
我在运行中
42
'''