python 装饰器
1 装饰器参数
1.1 装饰器和被装饰函数都不带参数
"""
装饰器装饰一个函数时,究竟发生了什么
"""
def decorator_hello(func):
print("decorator_hello called")
return func
@decorator_hello
def hello():
pass
"""
代码意义跟下面是一样的
def decorator_hello(func):
print("decorator_hello called")
return func
def hello():
pass
hello = decorator_hello(hello)
"""
装饰器没传参数的时候(隐性参数就是被装饰的函数对象)
1.2 装饰器带参数– 被装饰函数无参数
当需要在装饰函数的同时传入参数的话,那么就需要多包装一层,先传入参数返回一个装饰的函数, 这个返回的的函数就跟以前一样接受被装饰的函数(f)作为参数并且返回一个函数作为装饰最后的方法供调用
def decorator_hello1(args, args2):
print("decorator_hello1 called", args, args2)
def real_func(func2):
return func2
return real_func
@decorator_hello1("111", "222")
def hello():
print("xxxxxxx")
hello()
1.3 装饰器带参数– 被装饰函数带参数
需要再内嵌一层函数,这个函数接收俩个参数*args, **kwargs,用于接收函数传进来的参数
def decorator_hello1(args, args2):
print("decorator_hello1 called", args, args2)
def real_func(func2):
def handle_func(*args, **kwargs):
return func2(*args, **kwargs)
return handle_func
return real_func
@decorator_hello1("111", "222")
def hello(name1, name2):
print("name1 ", name1, "name2 ", name2)
hello("sysnap", "jim")
1.4 装饰器无参数– 被装饰函数带参数
def decorator_hello1(func):
def handle_func(*args, **kwargs):
return func(*args, **kwargs)
return handle_func
@decorator_hello1
def hello(name1, name2):
print("name1 ", name1, "name2 ", name2)
hello("sysnap", "jim")
如果已经确定函数的个数,可以直接写
def decorator_hello1(func):
def handle_func(name1, name2):
return func(name1, name2)
return handle_func
2 装饰器执行顺序
@A @B @C def f ():
等价于
f = A(B(C(f)))
再比如
def decorator_pre(func):
print("decorator_pre")
def handle_func(*args, **kwargs):
print("decorator_pre_1")
ret = func(*args, **kwargs)
return ret
return handle_func
def decorator_pre2(func):
print("decorator_pre2")
def handle_func(*args, **kwargs):
print("decorator_pre_2")
ret = func(*args, **kwargs)
return ret
return handle_func
@decorator_pre
@decorator_pre2
def hello(name1, name2):
print("name1 ", name1, "name2 ", name2)
等价于
hello = decorator_pre( decorator_pre2(hello) )
所以调用hello("1", "2")等价于 decorator_pre( decorator_pre2(hello) )("1", "2")
1 执行decorator_pre2(hello)打印decorator_pre2并返回 handle_func -> decorator_pre( handle_func )("1", "2")
2 执行decorator_pre( handle_func )打印decorator_pre并返回 handle_func
3 执行handle_func("1", "2")
再看
def decorator_2(args):
print("decorator_2")
def handle_func(func):
print("decorator_2_1")
return func
return handle_func
def decorator_pre2(func):
print("decorator_pre2")
def handle_func(*args, **kwargs):
print("decorator_pre_2")
ret = func(*args, **kwargs)
return ret
return handle_func
@decorator_2("xxxx")
@decorator_pre2
def hello(name1, name2):
print("name1 ", name1, "name2 ", name2)
等价于
(decorator_2("xxxx"))( decorator_pre2( hello ) )