本帖最后由 阿奇_o 于 2021-4-11 12:17 编辑
你们叫“修饰符”? 一般翻译为 装饰器 吧,毕竟 英文原词是 Decorator
Decorator 装饰器,本质是 函数的嵌套。 其特别在于,传递的是 所装饰/修饰下的那个函数对象。
理解的关键是:函数,竟然像 一个对象。函数也有“初始化”,函数初始化生成一个内存地址,和它真正被执行,是可以分开的!
# 1. 装饰器的本质是:函数嵌套。 外层函数返回 内层函数对象(内存地址),等待遇到小括号来执行。
def outer_func():
def inner_func():
print('Hi')
return inner_func
in_f = outer_func()
print(in_f)
in_f()
in_f()
# 2. 装饰器,就像 一种包装、包裹,一种特殊的封装方法。
def decorator_func():
print('--------------------')
def wrapper_func():
print('Hi, Hi.')
# return ? 如果这里返回的是传入函数对象,会怎样呢?
return wrapper_func
w_f = decorator_func()
w_f()
#继续扩展,如果 w_f 不叫 w_f,而是和 传入的函数对象名 同名呢?——这时,@decorator_func 就诞生了!
# 请看:
def my_decorator(decorated_func):
# print('------- xxxx -------') #暂不要理会这句
def wrapper_func(name, age):
print('------- 我在这就 装 饰一下 -------')
return decorated_func(name, age)
return wrapper_func
# @my_decorator
def hi(name, age):
print(f'Hi, 你好。我叫{name}, {age}岁。 交个朋友?')
# 1.
# 传入函数对象(参数暂不传入,因为参数需要加小括号,函数对象遇到小括号立马执行了,这里不是我们需要的)
decorated_func = my_decorator(decorated_func=hi)
decorated_func('王大锤', 2333)
# 2.
# 若用上 @my_decorator 这一语法,就可以简化成:
# hi('王大锤', 2333) # 注:因为装饰器的“装饰”,该函数执行的逻辑 就不完全等于其本身的定义。
# 2.0
# 它实际上 等价于 下面两句
# hi = my_decorator(hi) # 注意 要注释掉@my_decoratorn那句,不然print(装饰一下) 会 被执行两次,因为@my_decorator,相当于调用my_decorator(hi)
# hi('王大锤', 2333)
# 这样 以后 很方便地,只要你 @my_decorator 装饰下你自定义的函数,就可以 得到该装饰的附加效果。
# 典型应用,就是你代码想要实现的 计时功能(可看做是一种装饰),只要传入该函数对象 被@timelong 就可以被计时用时多久。
# 另一个典型应用是,触发写日记。 即创建一个专属的日记装饰器(如myLogger),再装饰和定义 一个日记信息函数(如 @myLogger def web_login(user, ip): ...
|