首先应该理解装饰器的原理是什么以及为什么使用装饰器?其实主要就是两个特性:
a、不改变原函数的内部结构和执行方式
b、为原函数增加功能
比如你现在有一个home函数,客户需要访问home页面,执行home(),返回到home页面,但是正常情况下我们需要检查客户是否已经登录,如果已经登录就直接回复home页面,如果没有登录就需要返回到登录页面,解决方式有两种:1、修改home函数,在函数内部做判断,但是这样其他人调用home函数就可能出现问题,2、使用装饰器,判断是否已经登录,在其他的页面也需要用到,比如首页也可以,这样利用率很高
1、不带参数的装饰器
def login(func):
def wrapper(*args, **kwargs):
print('do something')
return func(*args, **kwargs)
return wrapper
@login
def funcB(name):
print('my name is {}'.format(name))
if __name__ == '__main__':
funcB('alex')
运行结果是:
do something
my name is alex
其实这个装饰器的本质就是a=login(funcB),然后执行a('alex'),a是一个变量,此时我们也可以用原函数名funcB代替a,同样也是执行原函数,如下:
def login(func):
def wrapper(*args, **kwargs):
print('do something')
return func(*args, **kwargs)
return wrapper
def funcB(name):
print('my name is {}'.format(name))
if __name__ == '__main__':
funcB=login(funcB)
funcB('alex')
运行结果:
do something
my name is alex
两种方式运行结果一样,为了方便,一般就使用到了装饰器@func这种写法,调用的时候直接执行原函数即可
2、带参数的装饰器
def with_param(age):
def funA(func):
def wrapper(*args,**kwargs):
if len(*args):
return func(*args, **kwargs)
print('你的token是空的,请重新登录')
return wrapper
return funA
@with_param(18)
def home(token):
print('欢迎来到home,my token is {}'.format(token))
@with_param(16)
def index(token):
print('欢迎来到首页,my token is {}'.format(token))
if __name__ == '__main__':
home('agkdgaks')
home('')
index('dakgdjgahdfjya')
index('')
运行结果:
欢迎来到home,my token is agkdgaks
你的token是空的,请重新登录
欢迎来到首页,my token is dakgdjgahdfjya
你的token是空的,请重新登录