一、匿名函数
高级函数回顾:
1.接受一个或多个函数作为参数(在函数中传递函数代码);
2.将函数作为参数返回。
内置函数filter()
,参数中传入可迭代的结构,即filter(function,iterable)
,可以从序列中过滤出符合条件的元素,保存到一个新的序列中。
参数function:传递函数
参数iterable:需要过滤的序列
返回值:过滤后的新序列。
l = [1,2,3,4,5,6,7,8,9,10]
def tri(n):
if n % 3 == 0:
return True
print(list(filter(tri,l)))
打印出[3, 6, 9]
1.匿名函数:
又称lambda表达式。
lambda函数表达式专门用来创建一些简单的函数,是创建函数的另外一种形式。
语法:lambda 参数列表:返回值
。
如
result = lambda a,b:a+b
print(result)
打印
<function <lambda> at 0x0000024C52FF2EE8>
可见,函数没有名字,所以叫匿名函数。
传入参数
result = lambda a,b:a+b
print(result(10,20))
打印30
。
与
def fn(a,b):
return a + b
print(fn(10,20))
效果是一样的,但是更简洁。
l = [1,2,3,4,5,6,7,8,9,10]
tri = lambda i:i%3==0
r = filter(tri,l)
print(list(r))
与上面tri()
函数的效果是一致的。
lambda匿名函数俗称语法糖,可以减少代码量和优化程序,减少内存消耗。
2.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]
3.sort()方法:
该方法用来对列表中的元素进行排序,直接默认比较列表中元素的大小。
在该方法中可以接受一个关键字参数,即一个函数作为参数。
l = [34,554,67,897,436]
l.sort()
print(l)
打印[34, 67, 436, 554, 897]
同时可传递参数来对字符串长度进行比较。
l = ['ssd','adsd','frfrrffr','frfrsfrfs','rd']
l.sort(key=len)
print(l)
打印['rd', 'ssd', 'adsd', 'frfrrffr', 'frfrsfrfs']
。
还可以根据类型转换后的值进行比较:
l = ['34',554,'67',897,436]
l.sort(key=int)
print(l)
打印['34', '67', 436, 554, 897]
4.sorted()方法:
返回一个新的列表。
l = ['34',554,'67',897,436]
l2 = sorted(l,key=int)
print(l)
print(l2)
打印
['34', 554, '67', 897, 436]
['34', '67', 436, 554, 897]
二、闭包
将函数作为返回值返回,也是一种高级函数(俗称闭包)。
def fn():
#函数内部再定义一个函数
def inner():
print('In fn2()')
#将inner()函数作为返回值返回
return inner
print(fn())
打印<function fn.<locals>.inner at 0x000001E69ABC2EE8>
def fn():
#函数内部再定义一个函数
def inner():
print('In fn2()')
#将inner()函数作为返回值返回
return inner
r = fn()
r()
打印In fn2()
解释:r其实就是fn()返回的函数inner对象,再调用,就会打印,所以这个函数总是能返回fn()函数内部的变量,
def fn():
a = 10
#函数内部再定义一个函数
def inner():
print('In fn2()')
print(a)
#将inner()函数作为返回值返回
return inner
r = fn()
r()
打印
In fn2()
10
r是调用fn()后返回的函数,是在fn()内部定义的,并不是全局函数,所以这个函数总是能访问到fn()函数内部的变量。
闭包的好处:
通过闭包可以创建一些只有当前函数可以访问到的对象(可以将一些私有的数据藏到闭包中)。
应用:
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
不好的地方:nums是全局变量,会被任意访问到,可能会出现被修改、覆盖,从而导致本身的nums改变导致错误。
所以形成闭包:
def op_avg():
nums = []
def average(n):
nums.append(n)
return sum(nums)/len(nums)
return average
avg = op_avg()
print(avg(10))
print(avg(20))
print(avg(30))
结果与上面相同。
总结:
形成闭包的条件:
1.函数嵌套;
2.将内部函数作为返回值返回;
3.内部函数必须使用外部函数的变量。
闭包可以确保数据的安全。
三、装饰器
def add(a,b):
#求任意两个数的和
print('Start...')
r = a + b
print('End...')
return r
def multiply(a,b):
# 求任意两个数的积
print('Start...')
r = a * b
print('End...')
return r
r = add(1,2)
print(r)
打印
Start...
End...
3
这是添加了提示开始和结束的输出,但是如果函数较多,会出现一些问题:
※如果要修改的函数很多,修改起来很麻烦;
※不方便后期维护;
※会违反开闭原则(OCP)。
开闭原则:在开发的时候,要求可以开发对程序的扩展,但是要关闭对程序的修改。
def fn():
print('In fn()')
def fn2():
print('Start...')
fn()
print('End...')
fn2()
打印
Start...
In fn()
End...
又如
def add(a,b):
#求任意两个数的和
r = a + b
return r
def new_add(a,b):
print('Start...')
r = add(a,b)
print('End...')
return r
r = new_add(1,2)
print(r)
打印
Start...
End...
3
很显然,会出现一定问题,每扩展一个函数会定义一个新的函数,很麻烦。
四、装饰器使用
def start_end():
#用来对其他函数进行扩展,使其他函数可以在执行前打印开始和结束
#创建一个函数
def new_func():
pass
#返回函数
return new_func
f = start_end()
f2 = start_end()
print(f)
print(f2)
打印
<function start_end.<locals>.new_func at 0x0000018368DE2EE8>
<function start_end.<locals>.new_func at 0x0000018368DFB1F8>
扩展new_func后
def fn():
print('In fn()')
def start_end():
#用来对其他函数进行扩展,使其他函数可以在执行前打印开始和结束
#创建一个函数
def new_func():
print('Start...')
fn()
print('End...')
#返回函数
return new_func
f = start_end()
f()
打印
Start...
In fn()
End...
但是new_func是死的,变不了,失去了意义,所以可以在函数参数中传入被扩展的函数。
def fn():
print('In fn()')
def start_end(func):
#用来对其他函数进行扩展,使其他函数可以在执行前打印开始和结束
#创建一个函数
def new_func():
print('Start...')
func()
print('End...')
#返回函数
return new_func
f = start_end(fn)
f()
打印
Start...
In fn()
End...
当被扩展的函数有参数时,
def add(a,b):
#求任意两个数的和
r = a + b
return r
def start_end(func):
#用来对其他函数进行扩展,使其他函数可以在执行前打印开始和结束
#创建一个函数
def new_func(a,b):
print('Start...')
result = func(a,b)
print('End...')
return result
#返回函数
return new_func
f = start_end(add)
r = f(1,2)
print(r)
打印
Start...
End...
3
需要对任何函数进行扩展时,
def add(a,b):
#求任意两个数的和
r = a + b
return r
def fn():
print('In fn()')
def start_end(func):
#用来对其他函数进行扩展,使其他函数可以在执行前打印开始和结束
#创建一个函数
def new_func(*args,**kwargs): #*args接收所有位置参数,**kwargs接收所有关键字参数
print('Start...')
result = func(*args,**kwargs)
print('End...')
return result
#返回函数
return new_func
f = start_end(add)
f2 = start_end(fn)
r = f(1,2)
print(r)
f2()
打印
Start...
End...
3
Start...
In fn()
End...
python培训班:http://www.baizhiedu.com/python2019