装饰器
1、装饰器的知识点储备
"""
1、*args,**kwargs:形参中的作用汇总:*args是元组形式,**kwargs字典形式
2、*args,**kwargs:实参中的作用展开:
"""
# 一、储备知识
# 需求:我们要把传给wrapper的参数,原封不动的转嫁给index函数
# 1、*args和**kwargs
# def index(x,y):
# print(x,y)
# def wrapper(*args,**kwargs): # 形参中汇总: *args=(1,2,3,4,5),**kwargs={"a":1,"b":2}
# index(*args,**kwargs) # 实参中展开: index(*(1,2,3,4,5),**{"a":1,"b":2})
# index(1,2,3,4,5,a=1,b=2)
# wrapper(1,2,3,4,5,a=1,b=2) # 只要语法不错就可随意传,但是此处运行后会报错,因为index(x,y)
# TypeError: index() got an unexpected keyword argument 'a'
# wrapper(1,y=2)
# wrapper(y=2,x=1)
# 2、名称空间与作用域:名称空间的“嵌套”关系实在函数定义阶段,即检测语法的时候确定的。
# 名称空间的特点:不同的名称空间内可以存放相同的名称
# 3、函数对象:
# 可以把函数当作参数传入。
# 可以把函数当作返回值返回。
# def index():
# return 123
# def foo(func):
# return func
#
# foo(index) # 把函数当作参数传入
# 4、函数的嵌套定义:在一个函数内我可以在包一个函数
# def outter(func):
# def wrapper():
# pass
# return wrapper # 我要用到函数对象就不用加(),加括号就会得到返回值。
# 5、闭包函数:闭合在一个函数内
# def outter():
# x = 111
# def wrapper():
# print(x) # 包函数要访问外层的一个变量
# return wrapper
# f = outter() # f为全局变量,值来自闭包函数内的wrapper内存地址
# 思考一下函数是否被回收了?f = outter()应用到了wrapper所以没有被引用到。
# def f1():
# x=1
# y=2
# z=3
#
# def f2():
# print(x)
# print(y)
# print(z)
#
# f2()
# f1()
# 总结:两种传参的方式
# 方式一:通过函数的形式为函数体传值。
# 方式二:通过闭包的方式为函数体传值。
# 方式一实例:
# def wrapper(x):
# print(x)
#
# wrapper(1)
# wrapper(2)
# wrapper(3)
# 方式二实例:如果不能使用方式一,那么我们就要考虑使用闭包函数。
def outter(x):
# x = 1
def wrapper():
print(x)
return wrapper # outter内的wrapper那个函数的内存地址
wrapper = outter(1) # 得到的是一个内存地址,在不同的名称空间内,名字相同
wrapper() # 得到一个结果
方式二实例,如下图所示:

来源:https://www.cnblogs.com/liunaixu/p/12610893.html