双层语法糖
Python中,双层语法糖指的是同时使用了两种语法糖来简化代码的编写。一种语法糖是装饰器@,可以用于在函数定义时对函数进行修饰,增加一些额外的功能,如日志记录、性能测试、权限验证等等。
import time
def outer(func):
def get_time(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs) # 只能够统计index函数的时间
end_time = time.time()
print('执行时间:%s' % (end_time - start_time))
return res
return get_time
def login_auth(func):
# func = index
def auth():
username = input('username:>>>').strip()
password = input('password:>>>').strip()
# 2. 比较用户名和密码
if username == 'jerry' and password == '123':
# 执行函数
print('登录成功')
func()
else:
print('用户名或者密码错误')
return auth
@login_auth # index=login_auth(get_time) # index=auth
@outer # get_time=outer(index)
def index():
time.sleep(3)
print('from index')
index() # auth()
三层语法糖(多级)
Python的多级语法糖通常是指使用多个语法糖组合实现某种功能。
# 判断七句print执行顺序
def outter1(func1):
print('加载了outter1')
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1def
outter2(func2):
print('加载了outter2')
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outter3(func3):
print('加载了outter3')
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
@outter1
@outter2
@outter3
def index():
print('from index')
index()
装饰器的修复技术(了解)
import time
from functools import wraps
def outer(func):
@wraps(func) # 修复技术
def get_time():
start_time = time.time()
func() # 只能够统计index函数的时间
end_time = time.time()
print('执行时间:%s' % (end_time - start_time))
return get_time
# @outer # index=outer(index)
def index():
print('from index')
'''修复技术就是为了让装饰器伪装的更像'''
# index()
# print(index) # <function index at 0x000002F69849A940>
# print(index) # <function index at 0x000002F69849A940>
# help(index)
@outer
def home():
'''这是home函数'''
help(home)
有参装饰器(重要)
了解无参装饰器的实现原理后,我们可以再实现一个用来为被装饰对象添加认证功能的装饰器,实现的基本形式如下
def deco(func):
def wrapper(*args,**kwargs):
编写基于文件的认证,认证通过则执行res=func(*args,**kwargs),并返回res
return wrapper
如果我们想提供多种不同的认证方式以供选择,单从wrapper函数的实现角度改写如下
def deco(func):
def wrapper(*args,**kwargs):
if driver == 'file':
编写基于文件的认证,认证通过则执行res=func(*args,**kwargs),并返回res
elif driver == 'mysql':
编写基于mysql认证,认证通过则执行res=func(*args,**kwargs),并返回res
return wrapper
函数wrapper需要一个driver参数,而函数deco与wrapper的参数都有其特定的功能,不能用来接受其他类别的参数,可以在deco的外部再包一层函数auth,用来专门接受额外的参数,这样便保证了在auth函数内无论多少层都可以引用到
def auth(driver):
def deco(func):
……
return deco
此时我们就实现了一个有参装饰器,使用方式如下
# 先调用auth_type(driver='file'),得到@deco,deco是一个闭包函数,包含了对外部作用域名字driver的引用,@deco的语法意义与无参装饰器一样
@auth(driver='file')
def index():
pass
@auth(driver='mysql')
def home():
pass
可以使用help(函数名)来查看函数的文档注释,本质就是查看函数的doc属性,但对于被装饰之后的函数,查看文档注释
@timer
def home(name):
'''
home page function
:param name: str
:return: None
'''
time.sleep(5)
print('Welcome to the home page',name)
print(help(home))
'''
打印结果:
Help on function wrapper in module __main__:
wrapper(*args, **kwargs)
None
'''
在被装饰之后home=wrapper,查看home.name也可以发现home的函数名确实是wrapper,想要保留原函数的文档和函数名属性,需要修正装饰器
def timer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
wrapper.__doc__=func.__doc__
wrapper.__name__=func.__name__
return wrapper
————————————————
版权声明:本文为CSDN博主「森木在花开」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38104453/article/details/132810359