装饰器02
[TOC]
1 装饰器的语法糖
1.1 定义
为了简洁而优雅地使用装饰器,Python提供了专门的装饰器语法来取代index=timer(index)的形式,需要在被装饰对象的正上方单独一行添加@timer,当解释器解释到@timer时就会调用timer函数,且把它正下方的函数名当做实参传入,然后将返回的结果重新赋值给原函数名
1.2 基本使用
import timedef timmer(f):def wrapper(*args, **kwargs):start = time.time()res = f(*args, **kwargs)stop = time.time()print(\'run time is %s\' % (stop - start))return resreturn wrapper@timmer # index = timmer(index)def index():time.sleep(1)print(\'from index\')@timmer # home = time(home)def home(name):time.sleep(2)print(\'welcome to %s\' % name)return 123index()res = home("ccc")print(res)# from index# run time is 1.0003390312194824# welcome to ccc# run time is 2.0008108615875244# 123
2 有参装饰器
2.1 基本用法
@auth(driver=\'file\')def index():pass@auth(driver=\'mysql\')def home():pass
2.2 示例
import timedef login(x, engine=\'file\'):def auth(func):def wrapper(*args, **kwargs):print("========>", x)inp_user = input("username>>>>:").strip()inp_pwd = input("password>>>:").strip()if engine == "file":print("基于file认证")if inp_user == "egon" and inp_pwd == "123":print(\'login successful\')res = func(*args, **kwargs)return reselse:print(\'username or password error\')elif engine == \'mysql\':print("基于mysql认证")elif engine == "ldap":print("基于ldap认证")else:print("未知认证来源")return wrapperreturn auth@login(11, engine=\'file\') # @auth # index = auth(index) # index=wrapperdef index():time.sleep(1)print(\'from index\')@login(22, engine=\'file\') # @auth # home=auth(home) # home=wrapperdef home(name):time.sleep(2)print(\'home page,welcome %s\' % name)return 123index()home(\'egon\')# ========> 11# username>>>>:egon# password>>>:123# 基于file认证# login successful# from index# ========> 22# username>>>>:egon# password>>>:123# 基于file认证# login successful# home page,welcome egon
3叠加多个装饰器
3.1 基本用法
@deco3@deco2@deco1def index():pass
# 本质index=deco3(deco2(deco1(index)))
3.2 示例
def outter1(func1): # func1 = wrapper2的内存地址print(\'============>outter1\')def wrapper1(*args, **kwargs):print(\'=============wrapper1\')res1 = func1(*args, **kwargs)return res1return wrapper1def outter2(func2): # func2 = wrapper3的内存地址print(\'============>outter2\')def wrapper2(*args, **kwargs):print(\'=============wrapper2\')res2 = func2(*args, **kwargs)return res2return wrapper2def outter3(func3): # func3 = index的内存地址print(\'============>outter3\')def wrapper3(*args, **kwargs):print(\'=============wrapper3\')res3 = func3(*args, **kwargs)return res3return wrapper3# index = wrapper1的内存地址@outter1 # outter1(wrapper2的内存地址)-->wrapper1的内存地址@outter2 # outter2(wrapper3的内存地址)-->wrapper2的内存地址@outter3 # outter3(index的内存地址)-->wrapper3的内存地址def index():print(\'from index\')print(\'*\'*25)# print(index)index()# ============>outter3# ============>outter2# ============>outter1# *************************# =============wrapper1# =============wrapper2# =============wrapper3# from index
import timedef timmer(func):def wrapper1(*args, **kwargs):start = time.time()res = func(*args, **kwargs)stop = time.time()print(\'run time is:%s\' % (stop - start))return resreturn wrapper1def login(x, engine=\'file\'):def auth(func):def wrapper2(*args, **kwargs):print("========>", x)inp_user = input("username>>>>:").strip()inp_pwd = input("password>>>:").strip()if engine == "file":print("基于file认证")if inp_user == "egon" and inp_pwd == "123":print(\'login successful\')res = func(*args, **kwargs)return reselse:print(\'username or password error\')elif engine == \'mysql\':print("基于mysql认证")elif engine == "ldap":print("基于ldap认证")else:print("未知认证来源")return wrapper2return auth# 场景一@timmer@login(11, engine=\'file\')def index():time.sleep(1)print(\'from index\')index()# ========> 11# username>>>>:egon# password>>>:123# 基于file认证# login successful# from index# run time is:9.147817134857178# 场景二@login(11, engine=\'file\')@timmerdef index():time.sleep(1)print(\'from index\')index()# ========> 11# username>>>>:egon# password>>>:123# 基于file认证# login successful# from index# run time is:1.0001623630523682
4 wraps装饰器
4.1 定义
- functools模块下提供一个装饰器wraps专门用来帮我们保留原函数的文档和函数名属性,修正装饰器
4.2 示例
import timefrom functools import wrapsdef timmer(func):@wraps(func)def wrapper(*args, **kwargs):start = time.time()res = func(*args, **kwargs)stop = time.time()print(\'run time is:%s\' % (stop - start))return resreturn wrapper@ timmerdef index():"""index函数"""time.sleep(1)print(\'from index\')help(index)
5 匿名函数
"""def func(x, y): # func=函数的内存地址return x+y匿名函数:没有名字的函数应用场景:临时用一次,通常用于与其他函数配合使用"""# 无用调用方式f = lambda x, y: x+yprint(f)res = f(1, 2)print(res)# 调用方式1res = (lambda x, y: x+y)(1, 2)print(res)# 调用方式2salaries = {"egon": 1000,"alex": 2000,"jack": 3000,"rose": 4000}# 求薪资最高的那个人的名字def get_salary(name):return salaries[name]print(max(salaries, key = get_salary)) # roseprint(max(salaries, key=lambda name: salaries[name])) # roseprint(min(salaries, key=lambda name: salaries[name])) # egonprint(sorted(salaries)) # [\'alex\', \'egon\', \'jack\', \'rose\']print(sorted(salaries, key=lambda name: salaries[name])) # [\'egon\', \'alex\', \'jack\', \'rose\']print(sorted(salaries, key=lambda name: salaries[name], reverse=True)) # [\'rose\', \'jack\', \'alex\', \'egon\']# 返回绝对值print(abs(-11)) # 11print(abs(0)) # 0print(abs(11)) # 11# 如果是空或布尔值为真则返回Trueprint(all(\'\')) # Trueprint(all([])) # Trueprint(all([11, 22, 333, 0])) # False# 只要有一个值的布尔值为真就返回Trueprint(any(\'\')) # Falseprint(any([])) # Falseprint(any([0, None, \'\', 1])) # Trueprint(any([0, None, \'\'])) # False# ASCⅡ表:65-90 A-Zprint(chr(65)) # 数字->字母Aprint(ord(\'A\')) # 字母->数字65print(chr(90)) # Z# 进制转换print(bin(11)) # 十进制->二进制 0b1011print(oct(11)) # 十进制->八进制 0o13print(hex(11)) # 十进制->十六进制 0xb# 工厂函数intfloatstrlisttupledictsetboolbytes# 查看对象是否可调用print(callable(len)) # True# 面向对象重点classmethodstaticmethodsetattrgetattrdelattrhasattrdirexecl = eval("[1, 2, 3]")print(l[0]) # 1with open(\'user1.txt\', mode=\'wt\', encoding=\'utf-8\') as f:dic = {"ccc": "123", "zzz": "456", "yyy": "789"}f.write(str(dic))with open(\'user1.txt\', mode=\'rt\', encoding=\'utf-8\') as f:data = f.read()print(data, type(data)) # {\'ccc\': \'123\', \'zzz\': \'456\', \'yyy\': \'789\'} <class \'str\'>dic = eval(data)print(dic["ccc"]) # 123