一、基本需求:已存在tv方法且运行,先需要在tv方法被调用前使用login方法进行用户认证过程,且不能更改tv方法的执行过程
可使用认证函数包含运行函数的方法实现认证过程,但会改变原函数的调用方式:
def tv():
print("Welcome to TV page!")
def login(func): #传入一个需要login后执行的方法
print("Passed user verification.")
func() #传入的函数在验证函数内执行
tv = login(tv)
tv #login方法执行完成后返回NoneType,改变了tv函数的调用方法
'''console:
Passed user verification.
Welcome to TV page!
'''
若不改变原函数的执行方法,需要在login函数执行后返回原函数的内存地址
(1)无传入参数
def tv():
print("Welcome to TV page!")
def login(func): #传入一个需要login后执行的方法
print("Passed user verification.")
return func #进行完login过程后不执行传入的函数,直接返回内存地址
tv = login(tv)
tv() #login执行完后返回一个函数,不需要改变原函数的调用方式
(2)有传入参数
def tv(name): #使用形参接收传入参数
print("Welcome [%s] to TV page!"%name)
def login(func):
print("Passed user verification.")
return func
tv = login(tv)
tv('mumu') #直接传入参数
'''console:
Passed user verification.
Welcome [mumu] to TV page!
'''
二、装饰器实现
(1)无传入参数的简单装饰器
def login(func): #发现函数定义后开始扫描装饰器
print("Passed user verification.")
return func
@login #函数装饰器,意为"tv=login(tv)",运行login函数
def tv(name):
print("Welcome [%s] to TV page!"%name)
tv('mumu')
'''console:
Passed user verification.
Welcome to TV page!
'''
该程序执行后,运行到login装饰器不调用tv函数即开始执行login函数,与实际不符。可使用嵌套函数实现控制:
def login(func):
def inner(arg):
print("passed user verification")
func(arg)
return inner #装饰器执行后直接返回inner函数的内存地址
@login
def tv(name):
print("Welcome [%s] to TV page!"%name)
tv('mumu') #调用该函数时才会触发login函数执行
(2)有传入参数的复杂装饰器:存在统一框架时向装饰器传入函数。
定义如下统一框架,并将函数名作为参数传入装饰器:
def Before(request,kargs):
print("Before")
def After(request,kargs):
print("After")
def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs):
before_result = before_func(request,kargs)
main_result = main_func(request,kargs)
after_result = after_func(request,kargs)
return wrapper
return outer
@Filter(Before,After)
def index(request,kargs):
print("index")