基本概念
装饰器:用来装饰其他函数的,即为其他函数添加特定功能的函数。
装饰器函数的基本原则:
1、 装饰器不能改变被装饰函数的源码。
2、 装饰器不能修改被装饰函数的调用方式。
高阶函数:接受函数名作为形参,返回值中包含函数名。
嵌套函数:通过def关键字定义在另一个函数中的函数叫嵌套函数。
{
def foo():
print("in foo")
def boo():
print("in boo")
}
装饰器编写基本套路:
1.定义一个接受函数名作为参数的高阶函数
2.在高阶函数中定义一个嵌套函数,在该嵌套函数中:{1.封装想要添加的功能代码
2.调用作为参数传入的函数名
3.返回嵌套函数的函数名}
常见的几种装饰器类型:
1.被装饰函数带参数
2.装饰器本身带参数
3.被装饰函数带返回值
闭包的作用:
可以用来在一个函数与一组变量之间创建关联关系,在给定函数被多次调用的过程中,这些私有变量能够保持其私有性(保持运行环境与变量的状态)。
闭包的特征:
1.必须要有函数的嵌套,而且外层函数必须返回内层函数,外层函数相当于给内层函数提供了一个包装起来的运行环境,在这个包装的运行环境里面,内层函数可完全自己掌握自由变量的值。
2.内层函数一定要用到外层函数中定义的自由变量。
装饰器与闭包的不同点:
装饰器:
1.外层函数成为装饰器
2.装饰器的外层函数主要是提供被装饰函数的引用
3.装饰器的外层函数不一定要提供变量
4.装饰器的目的:为被装饰函数提供额外的功能
5.从形式上看,闭包是装饰器的子集
闭包:
1.外层函数称为闭包
2.闭包的外层函数主要是为了提供自由变量
3.闭包的外层函数必须提供自由变量,否则闭包无意义
4.闭包的目的是保存函数运行环境和局部变量值
高阶函数和嵌套函数
高阶函数:
def foo():
print('in foo')
def gf(func):
print(func) #运行foo函数之前附加的功能语句
func()
嵌套函数
def foo():
print("in foo")
def boo():
print("in boo")
被装饰函数带参数
import time
"""
#错误1.
# def timer(fanc):
# def gf():
# start_time = time.time()
# fanc()
# end_time = time.time()
# print('运行时间:', end_time - start_time)
# return gf
# @timer #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
# def foo(name):
# time.sleep(3)
# print('in foo',name)
# #foo=gf
# foo() #"TypeError: foo() missing 1 required positional argument: 'name'" 在调用一个函数foo()时,该函数需要一个名为name的参数,但在调用时没有提供它。
#错误2.
# def timer(fanc):
# def gf():
# start_time = time.time()
# fanc()
# end_time = time.time()
# print('运行时间:', end_time - start_time)
# return gf
# @timer #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
# def foo(name):
# time.sleep(3)
# print('in foo',name)
# #foo=gf
# foo('123') #"TypeError: timer.<locals>.gf() takes 0 positional arguments but 1 was given" timer函数中的局部函数gf()不接受任何参数,但在调用时却传递了一个参数。
"""
# def timer(fanc):
# def gf(name):
# start_time = time.time()
# fanc(name)
# end_time = time.time()
# print('运行时间:', end_time - start_time)
# return gf
#
# @timer #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
# def foo(name): #被装饰的函数要添加参数,要在装饰函数的嵌套函数中添加参数(要传入一个参数时使用)
# time.sleep(3)
# print('in foo',name)
# #foo=gf
# foo('123') #gf(name)
def timer(fanc):
def gf(*args,**kwargs): #通过不定量参数来自适应被装饰函数的参数
start_time = time.time()
fanc(*args,**kwargs)
end_time = time.time()
print('运行时间:', end_time - start_time)
return gf
@timer #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
def foo(name,age): #被装饰的函数要添加多个参数,要在装饰函数的嵌套函数中添加*args,**kwargs(建议无脑写)
time.sleep(3)
print('in foo',name,age)
#foo=gf
foo('123',11) #gf(name)
"""
*args(位置参数)
作用:将函数接收到的所有位置参数打包成一个元组。
使用场景:当函数需要接受不确定数量的位置参数时。
**kwargs(关键字参数)
作用:将函数接收到的所有关键字参数打包成一个字典。
使用场景:当函数需要接受不确定数量的关键字参数时。
在装饰器中的应用
参数解包:调用函数时,func(*args)将元组args解包为位置参数,func(**kwargs)将字典kwargs解包为关键字参数。
通用性:装饰器通过*args和**kwargs适配所有被装饰函数,无需针对参数修改装饰器代码。
总结
*args:捕获多余位置参数 → 元组。
**kwargs:捕获多余关键字参数 → 字典。
二者结合使用,可确保函数或装饰器灵活处理任意参数形式。
"""
装饰器本身带参数
import time
"""
错误1.
# def timer(fanc):
# def gf(*args,**kwargs):
# start_time = time.time()
# fanc(*args,**kwargs)
# end_time = time.time()
# print('运行时间:', end_time - start_time)
# return gf
#
# @timer(time_type='minites') #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
# def foo(name,age):
# time.sleep(3)
# print('in foo',name,age)
# #foo=gf
# foo('123',11) #gf(name)
# TypeError: timer() got an unexpected keyword argument 'time_type' 收到了一个未预期的关键字参数 'time_type'
错误2.
# def timer(time_type,fanc):
# print(time_type)
# def gf(*args,**kwargs):
# start_time = time.time()
# fanc(*args,**kwargs)
# end_time = time.time()
# print('运行时间:', end_time - start_time)
# return gf
#
# @timer(time_type='minites') #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
# def foo(name,age):
# time.sleep(3)
# print('in foo',name,age)
# #foo=gf
# foo('123',11) #gf(name)
# TypeError: timer() missing 1 required positional argument: 'fanc' timer()缺少fanc参数
"""
def timer(time_type):
print(time_type)
def outer(fanc): #加一层嵌套函数,并接受被装饰器函数名作为参数
def inner(*args,**kwargs): #通过不定量参数来自适应被装饰函数的参数
start_time = time.time()
fanc(*args,**kwargs)
end_time = time.time()
print('运行时间:', end_time - start_time)
return inner
return outer
@timer(time_type='minites') #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
def foo(name,age):
time.sleep(3)
print('in foo',name,age)
#foo=gf
foo('123',11) #gf(name)
被装饰函数带返回值
import time
def timer(time_type):
print(time_type)
def outer(fanc): #加一层嵌套函数,并接受被装饰器函数名作为参数
def inner(*args,**kwargs): #通过不定量参数来自适应被装饰函数的参数
start_time = time.time()
res = fanc(*args,**kwargs)
end_time = time.time()
print('运行时间:', end_time - start_time)
return res
return inner
return outer
@timer(time_type='minites') #foo = timer(foo) 将原函数 `foo` 作为参数传递给装饰器 `timer`
def foo(name,age):
time.sleep(3)
print('in foo',name,age)
return name
#foo=gf
print(foo('123',11)) #inner
闭包
func_list = []
for i in range(3):
def deco(i): #i通过参数传入后,变成了myfunc的自由变量
def myfunc(a):
return i+a
return myfunc
func_list.append(deco(i))
for f in func_list:
print(f(1))
# func_list = []
# for i,j in [(1,2),(3,4),(5,6)]:
# def deco(i): #i通过参数传入后,变成了myfunc的自由变量
# b=j
# def myfunc(a):
# print(b)
# return i+a
# return myfunc
# func_list.append(deco(i))
#
# for f in func_list:
# print(f(1))
Comments NOTHING