高级函数
1、特点:接收一个或多个作为参数
2、将函数作为返回值
#满足任意一个特点就是高级函数
# 定义一个函数,可以将指定列表的偶数,保存到一个新的变量当中
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def sum(num): # 函数形参用来做判断
list1 = []
for i in num: # 循环遍历
if i % 2 == 0: # 判断列表中的奇偶性
list1.append(i)
# 返回新的列表
return list1
print(sum(l))
运行结果:
[2, 4, 6, 8, 10]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fn2(i):
if i % 2 == 0:
return True
def fn3(i):
if i > 5:
return True
return False
new_list = []
def fn4(i):
if i % 3 == 0:
return True
return False
def fn(func, lst):
for n in lst:
if func(n):
new_list.append(n)
return new_list
print(fn(fn4,l))
运行结果:
[3, 6, 9]
语法:filter(function,iterable)
#可以从序列当中过滤出符合条件的元素,保存到一个新的序列中
#参数——传递函数,参数二——需要过滤的序列
#返回值,过滤后的新列表
当我们使用一个函数作为参数时,实际上我们就是将指定代码传递给了目标函数
匿名函数
#lambda表达式
#lambda函数表达式专门用来创建一些简单的函数,它是函数创建的另外一种方式
#语法:lambda,参数列表:返回值
例子:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fn2(i):
if i % 2 == 0:
return True
r=list(filter(fn2,l)) #filter可以从序列当中过滤出符合条件的元素(顾名思义:使用函数里的功能,任何保存到一个新的列表中)
print(r)
运行结果:
[2, 4, 6, 8, 10]
def fn5(a,b):
return a+b
print((lambda a,b:a+b)(10,20))
运行结果:
30
普遍写法:
fn5 =lambda a,b:a+b
print(fn5(10,30))
运行结果:
40
例子:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = filter(lambda i: i % 2 == 0, l) #好处:只会调用一次调用后就会从内存当中释放
print(list(r))
运行结果:
[2, 4, 6, 8, 10]
map函数()
#map()函数可以对可迭代对象中所有的元素做指定操作,然后将其添加到一个新的对象返回
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = map(lambda i:i+1,l)
print(list(r))
运行结果:
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
sort()
该方法用来对列表当中的元素进行排序
#.sort()方法是直接默认比较列表中的元素大小
#在.sort()函数中可以接收一个关键字参数key
#key需要一个函数作为参数
#需求将l中的元素按长度输出
l = ['aa','bbb','cccc','d','nnnnn']
l.sort(key=len)
print(l)
运行结果:
['d', 'aa', 'bbb', 'cccc', 'nnnnn']
闭包
形成闭包的条件:
1、函数嵌套
2、将内部函数作为返回值返回
3、内部函数必须使用外部函数的变量
# 闭包
# 将函数作为返回值,也是高阶函数(闭包)
def fn2():
# 在函数内部定义一个函数
def inner():
print('我是fn2')
# 将函数内部inner作为返回值返回
return inner
r = fn2()
r()
运行结果:
我是fn2
所以r()这个函数总能访问fn()函数的内部变量
闭包的好处是:
通过闭包可以创建一些只有当前函数可以访问到的变量(可以将一些私有的数据藏到闭包当中)
nums = [] #定义在外面相当于定义全局变量,在开发过程中,定义全局变量容易被项目开发者不小心调用,就会产生一些数据丢失
# 创建一个函数,用来求平均值
nums = []
def average(n):
nums.append(n)
# 求平均值
return sum(nums) / len(nums)
print(average(10))
print(average(20))
print(average(30))
运行结果:
10.0
15.0
20.0
所以我们需要闭包。代码如下:
def make_nonter():
#创建一个空的列表
nums = []
def average(n):
nums.append(n)
# 求平均值
return sum(nums) / len(nums)
return average
r = make_nonter()
print(r(20))
num = []
print(r(30))
运行结果:
20.0
25.0
这样就不会覆盖结果,就起到了一个闭包的效果
形成闭包的条件:1、函数嵌套。
2、将内部函数做为返回值返回。
3、内部函数必须使用到外部函数变量
装饰器的引用如下:
def add(a, b):
# 求任意两个数的和
print('计算开始...')
r = a + b
print('计算结束...')
return r
r = add(1, 2)
print(r)
def mul(a, b):
# 求任意两个数的积
return a * b
r = mul(1, 2)
print(r)
#通过以上的步骤来实现当前的这个需要我们发现一些问题
#1、如果要修改的函过多,修改起来比较麻烦
#2、不方便后期维护
#3、会违反开闭原则(OCP)
#我们在开发的时候,要求可以开发对程序的扩展,但是要关闭对程序的扩展
运行结果:
计算开始...
计算结束...
3
2
方法:
#在不修改原函数的情况下,来对函数进行扩展
def fn():
print('我是fn函数')
#创建一个新的函数
def fn2():
print('函数开始执行')
fn() #对fn函数进行扩展,起到装饰器的效果
print('函数执行结束')
fn2()
运行结果:
函数开始执行
我是fn函数
函数执行结束
def add(a, b):
# 求任意两个数的和
# print('计算开始...')
r = a + b
# print('计算结束...')
return r
def new_add(a,b):
print('计算开始...')
r = add(a,b) #在没有修改原函数的前提下,增加了功能
print(r)
print('计算结束')
new_add(1,2)
运行结果:
计算开始...
3
计算结束
装饰器的使用如下:
def fn():
print('我是fn函数')
#装饰器的使用
def start_end():
#用来对其他函数进行扩展,使其他函数可以在执行前打印执行开始,执行后打印结束
#创建一个函数
def new_function():
print('计算开始...')
fn() #对函数进行扩展
print('计算结束')
#返回这个函数
return new_function
r = start_end()
r()
运行结束:
计算开始...
我是fn函数
计算结束
在一次进行扩展,把程序不写死
def fn():
print('我是fn函数')
#装饰器的使用
def start_end(old):
#用来对其他函数进行扩展,使其他函数可以在执行前打印执行开始,执行后打印结束
#创建一个函数
def new_function():
print('计算开始...')
old()
print('计算结束')
#返回这个函数
return new_function
r = start_end(fn)
r()
运行结束:
计算开始...
我是fn函数
计算结束
需求:当传递100个参数时,代码如下:最终结果
需要使用到 *agrs 接收所有的位置参数, **kwargs接收所有的关键字参数
def fn():
print('我是fn函数')
def add(a, b):
# 求任意两个数的和
# print('计算开始...')
r = a + b
# print('计算结束...')
return r
# 装饰器的使用
def start_end(old):
# 用来对其他函数进行扩展,使其他函数可以在执行前打印执行开始,执行后打印结束
# 创建一个函数
def new_function(*args, **kwargs):
print('计算开始...')
# 调用被扩展的函数
result = old(*args,**kwargs)
print('计算结束')
return result
# 返回这个函数
return new_function
r = start_end(fn)
r()
r2 = start_end(add)
result = r2(50,100)
print(result)
运行结果:
计算开始...
我是fn函数
计算结束
计算开始...
计算结束
150
总结:向start_end(ord)这种函数我们就称之为装饰器,通过装饰器可以在不修改原来函数的基础之上对函数进行扩展,在开发当中,我们都是通过对装饰器来扩展函数的功能