理解装饰器之前先要理解闭包
-
闭包
定义
:在一个函数内部的函数,同时内部函数又引用了外部函数的变量。
本质
:闭包是将内部函数和外部函数的执行环境绑定在一起的对象。
优点
:内部函数可以使用外部变量。
缺点
:外部变量一直存在于内存中,不会在调用结束后释放,占用内存。
作用
:实现python装饰器。 -
闭包三要素:
– 必须有一个内嵌函数。
– 内嵌函数必须引用外部函数中变量。
– 外部函数返回值必须是内嵌函数。 -
闭包函数的调用方式:
变量 = 外部函数名(参数)
变量(参数) -
函数名变量存储着函数内存地址
def test(): print("这是test函数") print(test) # <function test at 0x000001D2BE18C1E0> test() # 这是test函数
伪代码示例:
def 外部函数名(参数):
外部变量
def 内部函数名(参数):
使用外部变量
# 仅返回内部函数名(内部函数的内存地址)
return 内部函数名
代码示例:
def test(name: str):
age = 18
def my_test():
print("name:", name)
print("age:", age)
# 仅返回内部函数名(内部函数的内存地址)
return my_test
print(test) # test函数的内存地址
print(test(name="test")) # test函数内部函数my_test 函数的内存地址
result = test(name="test") # 使用变量接收test 函数返回的 my_test函数内存地址
result() # 相当于 my_test()
装饰器
而装饰器decorators,正式利用了闭包的特性
-
定义
在不改变原函数的调用以及内部代码情况下,为其添加新功能的函数。
-
伪代码示例
def 函数装饰器名称(func): 需要添加的新功能 def 内嵌函数名(*args, **kwargs): 需要添加的新功能 return func(*args, **kwargs) return 内嵌函数名
-
装饰器的使用
使用@符号,直接在函数上方添加装饰器@函数装饰器名称 想要装饰的函数()
-
本质:
使用“@函数装饰器名称”修饰原函数,等同于创建与原函数名称相同的变量,关联内嵌函数;故调用原函数时执行内嵌函数。
原函数名称 = 函数装饰器名称(原函数名称)
-
代码示例
- 定义两个普通函数,实现打招呼,与说再见功能