装饰器是python基础中的重点。
装饰器就是在符合开放封闭的原则下给你的代码加功能。其出现是为了遵循开放-封闭原则。
封闭:已实现的功能代码块不应该被修改。
开放:对现有功能的扩展开放。
示例:
user_status = False # 用户登录了就把这个改成True def login(func): # 把要执行的模块从这里传进来 def wrapper(*args,**kwargs): _username = "alex" # 假装这是DB里存的用户信息 _password = "123" # 假装这是DB里存的用户信息 global user_status if user_status == False: username = input("user:") password = input("pasword:") if username == _username and password == _password: print("welcome login....") user_status = True else: print("wrong username or password!") if user_status == True: func(*args,**kwargs) # henan() return wrapper def home(): print("---首页----") def america(): # login() #执行前加上验证 print("----欧美专区----") @login def japan(): print("----日韩专区----") @login # henan = login(henan),只要@了,不执行henan(),也会自动执行这段代码,前提是login必须是一个函数名。 # 返回wrapper的内存地址 def henan(style): print("----河南专区----", style) henan('豫剧')
解析:henan = login(henan),是把henan当做参数传给了login。这时候,henan这个函数里的代码并没有执行,而是返回了wrapper, 当执行henan的时候等于是执行了wrapper,
wrapper里的代码是进行用户认证,如果认证通过就会执行func(),在这个例子里也就是henan(),而henan里的代码在内部已经封装到了上一层的局部变量里面,所以会去上一层找henan的代码执行(闭包)
装饰器带参数
@login返回wrapper的内存地址,执行henan('豫剧')也就是执行wrapper('豫剧'),所以wrapper定义的接收任何参数,验证成功后执行func('豫剧'),也就是执行henan('豫剧'),
'豫剧'是wrapper传的参数'。这里要用非固定参数,因为别的模块可能不传参数或者传多个参数。
装饰器带参数进阶
示例
# 允许用户选择用qqweiboweixin认 user_status = False # 用户登录了就把这个改成True def login(auth_type): # 把要执行的模块从这里传进来 def outer(func): # henan def wrapper(*args, **kwargs): _username = "alex" # 假装这是DB里存的用户信息 _password = "123" # 假装这是DB里存的用户信息 global user_status if user_status == False: username = input("user:") password = input("pasword:") if username == _username and password == _password: user_status = True else: print("wrong username or password!") if user_status == True: print(auth_type, '登陆') func(*args, **kwargs) # henan() return wrapper return outer def home(): print("---首页----") def america(): # login() #执行前加上验证 print("----欧美专区----") # @login('weixin') def japan(): print("----日韩专区----") ''' @login('qq')其实等于 henan = login('qq')(henan) = wrapper 1.先执行login('qq'),返回outer 2.相当于这里赋的是@outer了,也就是henan=outer(henan),然后返回wrapper。 这样执行henan()这个函数的时候,由于闭包原则,也可以使用login带的'qq'这个参数。 ''' @login('qq') def henan(style): print("----河南专区----", style) henan('豫剧') # wrapper('豫剧')
参考:https://www.cnblogs.com/alex3714/articles/5765046.html