装饰器:在不修改函数源代码的基础上,添加函数功能
例如:
1 def log_time(func): # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用
2 def make_decorater():
3 print('现在开始装饰')
4 func()
5 print('现在结束装饰')
6 return make_decorater # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater
7
8 @log_time # 此行代码等同于,test=log_time(test)=make_decorater
9 def test():
10 print('我是被装饰的函数')
11 test() # test()=make_decorater()
当被装饰的函数有形参时:
def log_time(func):
def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
print('现在开始装饰')
test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
print('现在结束装饰')
return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。
return make_decorater
@log_time
def test(num):
print('我是被装饰的函数')
return num+1
a = test(2) # test(2)=make_decorater(2)
print(a)
当@装饰器后有参数时:
def get_parameter(*args,**kwargs): # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/'
def log_time(func):
def make_decorater():
print(args,kwargs)
print('现在开始装饰')
func()
print('现在结束装饰')
return make_decorater
return log_time
@get_parameter('index.html/')
def test():
print('我是被装饰的函数')
# return num+1
test() # test()=make_decorater()
两个装饰器同时修饰一个函数(重点看执行顺序):
def log_time1(func):
def make_decorater(*args,**kwargs):
print('1现在开始装饰')
test_func = func(*args,**kwargs)
print('1现在结束装饰')
return test_func
return make_decorater
def log_time2(func):
def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
print('2现在开始装饰')
test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
print('2现在结束装饰')
return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。
return make_decorater
@log_time1
@log_time2
def test(num):
print('我是被装饰的函数')
return num+1
a = test(2) # test(2)=make_decorater(2)
print(a)