Python 装饰器相关知识
-
定义:
在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。
-
开放封闭原则:
- 开放:对代码的拓展是开放的,
- 封闭:对源码的修改是封闭的,
-
装饰器:
-
完全遵循开放封闭原则。
-
在不改变原函数代码以及调用方式的前提下,为其增加新的功能。
-
装饰器本质是一个函数。
-
标准版装饰器格式,Python有个代码优化,叫语法糖:@+装饰器函数名。
-
具体实现:装饰器函数放在代码的import语句下面,然后在需要装饰的函数前面加上
@装饰器名
,下面再调用该被装饰的函数时将执行装饰后的函数,调用方法没有任何改变,参数能够照样传进去,返回值也应该可以原样返回。 -
举例:不完整版,带参数,但没有返回值
def timer(func): # func = home def inner(*args,**kwargs): start_time = time.time() func(*args,**kwargs) end_time = time.time() print(f'此函数的执行效率为{end_time-start_time}') return inner @timer # home = timer(home) def home(name,age): time.sleep(3) # 模拟一下网络延迟以及代码的效率 print(name,age) print(f'欢迎访问{name}主页') home('太白',18)
-
举例:带参数和返回值的装饰器,标准版
def timer(func): # func = home def inner(*args,**kwargs): start_time = time.time() ret = func(*args,**kwargs) end_time = time.time() print(f'此函数的执行效率为{end_time-start_time}') return ret return inner @timer # home = timer(home) def home(name,age): time.sleep(3) # 模拟一下网络延迟以及代码的效率 print(name,age) print(f'欢迎访问{name}主页') return 666 home('太白',18)
-
标准版的装饰器模板:
def 装饰器函数名(f): # f参数用于传入被装饰函数名 def inner(*args,**kwargs): # 内层的嵌套函数需要传参 '''添加被装饰函数执行之前的工作''' ret = f(*args,**kwargs) # 调用被装饰函数,需要接收原函数返回值 '''添加被装饰函数执行之后的工作''' return ret # 将被装饰函数的返回值给返回出去 return inner
-
-
装饰器的应用:
-
登录认证,用得比较多,还有各类日志。
模拟博客园登录,需求:在访问每个功能模块之前必须先验证是否已经登录,没有登录不让访问,如没有账号就注册一个再登录,三次登录不成功就退出整个程序。
status_dict = { # 登录用户状态 'username': None, 'status': False, } def get_usr_pwd(): pass def register(): pass def login(): # 登录模块,登录3次不成功则退出 pass def auth(f): # 装饰器模板 def inner(*args, **kwargs): if status_dict['status'] == False: # 如果登录状态为假,则进入登录模块 status_dict['username'],status_dict['status'] = login() # 调用登录模块并接收登录状态 if status_dict['status'] == True: # 如果登录成功,则运行被装饰函数 ret = f(*args, **kwargs) else: ret = f(*args, **kwargs) return ret return inner @auth # article=auth(article) def article(): print(f'欢迎{status_dict["username"]},访问文章页面。') @auth def comment(): print('欢迎访问评论页面') @auth def dariy(): print(f'欢迎{status_dict["username"]},访问日记页面。') article() comment() dariy()
-