A、闭包
如果在一个内部函数中对外部函数作用域的变量进行引用,那么内部变量就会被称为闭包,闭包的三个条件
- 存在于嵌套关系的函数中
- 嵌套的内部函数引用外部函数的变量
- 嵌套的外部函数会将内部函数名作为返回值返回
def outer(start):
count = [start]
# 内部函数
def inner():
count[0] += 1
return count[0]
# 返回内部函数
return inner()
num = outer(5)
print(num)
运行结果:
6
B、装饰器
1、什么是装饰器
装饰器本质上也是一个函数,它可以在不改动其它函数的前提下,对函数的功能进行扩充。通常情况下,用于以下几种情况:
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验
- 缓存
def wrap(func):
print('正在装饰')
def inner():
print('验证装饰')
func()
return inner
@wrap # test = wrap(test)
def test():
print("test")
test()
运行结果:
正在装饰
验证装饰
test
执行过程:
- 当程序执行test()时,发现test()函数上面有@wrap,所以会先执行@wrap。(@wrap等介于:test = wrap(test)),它可以分为两步:
① 执行wrap(test) ,将函数名 test 作为形参,传递给 wrap 。在调用wrap函数的过程中,将形参func指向test() 函数体,并将inner() 函数的引用返回给wrap(test),作为wrap(test)的返回值
② 这时 test 指向的就是inner() 函数,完成了函数test()的装饰 - 调用 test() 指向的函数,因为此时指向的是inner()函数,所以调用test()函数,就相当于调用inner()函数,由于在第一步时 func形参指向了test()函数体,所以执行func(),就执行了test()函数体
2、多个装饰器
多个装饰器可以应用于一个函数,它们的调用顺序时由下而上
def wrap2(func):
print('正在装饰2')
def inner():
print('验证装饰2')
func()
return inner
def wrap1(func):
print('正在装饰1')
def inner():
print('验证装饰1')
func()
return inner
@wrap2 # test = wrap2(test)
@wrap1 # test = wrap1(test)
def test():
print("test")
test()
运行结果:
正在装饰1
正在装饰2
验证装饰2
验证装饰1
test
- 程序会显执行@wrap1然后执行@wrap2,这两个执行完后就已经装饰完毕会输出:
正在装饰1 正在装饰2
- 装饰完毕后,执行test(),程序会按照从上向下的顺序运行,最终输出结果为:
验证装饰2 验证装饰1 test
3、装饰器对带有参数的函数装饰
def wrap(func):
print('正在装饰')
def inner(hello):
print('验证装饰')
func(hello)
return inner
@wrap
def smcs(hello):
print(hello,'三木成森')
smcs('你好')
运行结果:
正在装饰
验证装饰
你好 三木成森
在不确定是参数个数或类型的时候,可以使用不定长参数
4、装饰器对带有返回值的函数装饰
def wrap(func):
def inner():
return func()
return inner
@wrap
def smcs():
return '三木成森'
print(smcs())
运行结果:
三木成森
5、带有参数的装饰器
def func_1(args):
def wrap(func):
def inner():
print(args)
return func()
return inner
return wrap
@func_1(123)
def smcs():
return '三木成森'
print(smcs())
运行结果:
123
三木成森
@func_1等介于:smcs = func_1(123)(test)
由于函数func_1(args)的返回值是wrap,所以又等介于:
smcs = wrap(test)
C、常见Python内置函数
1、map函数
map函数会根据提供的函数对指定的序列做映射
map函数的定义如下:
map(function, iterable,....)
第一个参数表示的是函数名,第二个参数可以是序列,支持迭代的容器或迭代器,当调用map函数时,iterable里的每个元素都会调用function函数
func = lambda x:x*x
data = map(func,[1,2,3])
print(list(data))
运行结果:
[1, 4, 9]
这是对每个元素求平方
当传入的函数需要两个参数时,需要传入两个列表
func = lambda x, y:x+y
data = map(func,[1,2,3],[4,5,6])
print(list(data))
运行结果:
[5, 7, 9]
在Python3之前,如果函数为None的话,相当于合并为元组
如果,两个序列,元素个数不一致,那么少的元素就会以None补齐
在Python3之后,如果传入的函数时None,就等同于Zip函数,另外map无法处理两个序列不一致,对应位置操作数类型不一致,它们都会报错
2、filter函数
filter函数,会对指定序列执行过滤操作
定义如下:
filter(function, iterable)
第一个参数可以时函数名或者None,第二个参数iterable可以时序列、支持迭代的容器或迭代器,返回值为迭代对象,funtion只能接收一个参数,且该函数的返回值为布尔值
filter函数的作用时以参数迭代器中的每个元素分别调用funtion函数,最后返回的迭代器包含调用结果为True的元素
func = lambda x:x%2
result = filter(func, [1, 2, 3, 4, 5])
print(list(result))
运行结果:
[1, 3, 5]
3、reduce函数
reduce函数会对参数迭代器中的元素进行累积
from functools import reduce
func = lambda x, y:x * y
result = reduce(func, [-1, 2, 3, 4], -5)
print(result)
运行结果:
120