• day010|python之装饰器


    装饰器02

    1 装饰器的语法糖

    1.1 定义

    为了简洁而优雅地使用装饰器,Python提供了专门的装饰器语法来取代index=timer(index)的形式,需要在被装饰对象的正上方单独一行添加@timer,当解释器解释到@timer时就会调用timer函数,且把它正下方的函数名当做实参传入,然后将返回的结果重新赋值给原函数名

    1.2 基本使用

    import time
    
    def timmer(f):
        def wrapper(*args, **kwargs):
            start = time.time()
            res = f(*args, **kwargs)
            stop = time.time()
            print('run time is %s' % (stop - start))
            return res
        return 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 123
    
    
    index()
    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 time
    
    def 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 res
                    else:
                        print('username or password error')
                elif engine == 'mysql':
                    print("基于mysql认证")
                elif engine == "ldap":
                    print("基于ldap认证")
                else:
                    print("未知认证来源")
            return wrapper
        return auth
    
    
    @login(11, engine='file')  # @auth  # index = auth(index)  # index=wrapper
    def index():
        time.sleep(1)
        print('from index')
    
    
    @login(22, engine='file')  # @auth  # home=auth(home)  # home=wrapper
    def home(name):
        time.sleep(2)
        print('home page,welcome %s' % name)
        return 123
    
    
    index()
    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
    @deco1
    def 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 res1
        return wrapper1
    
    
    def outter2(func2):  # func2 = wrapper3的内存地址
        print('============>outter2')
        def wrapper2(*args, **kwargs):
            print('=============wrapper2')
            res2 = func2(*args, **kwargs)
            return res2
        return wrapper2
    
    
    def outter3(func3):  # func3 = index的内存地址
        print('============>outter3')
        def wrapper3(*args, **kwargs):
            print('=============wrapper3')
            res3 = func3(*args, **kwargs)
            return res3
        return 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 time
    
    def timmer(func):
    	def wrapper1(*args, **kwargs):
    		start = time.time()
    		res = func(*args, **kwargs)
    		stop = time.time()
    		print('run time is:%s' % (stop - start))
    		return res
    	return wrapper1
    
    
    def 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 res
    			else:
    				print('username or password error')
    			elif engine == 'mysql':
    				print("基于mysql认证")
    			elif engine == "ldap":
    				print("基于ldap认证")
    			else:
    				print("未知认证来源")
    		return wrapper2
    	return 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')
    @timmer
    def 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 time
    from functools import wraps
    
    
    def 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 res
        return wrapper
    
    
    @ timmer
    def index():
        """index函数"""
        time.sleep(1)
        print('from index')
    
    
    help(index)
    

    5 匿名函数

    """
    def func(x, y):  # func=函数的内存地址
        return x+y
    
    匿名函数:没有名字的函数
    应用场景:临时用一次,通常用于与其他函数配合使用
    """
    
    # 无用调用方式
    f = lambda x, y: x+y
    print(f)
    res = f(1, 2)
    print(res)
    
    # 调用方式1
    res = (lambda x, y: x+y)(1, 2)
    print(res)
    
    # 调用方式2
    salaries = {
        "egon": 1000,
        "alex": 2000,
        "jack": 3000,
        "rose": 4000
    }
    # 求薪资最高的那个人的名字
    
    def get_salary(name):
        return salaries[name]
    
    print(max(salaries, key = get_salary))  # rose
    print(max(salaries, key=lambda name: salaries[name]))  # rose
    print(min(salaries, key=lambda name: salaries[name]))  # egon
    print(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))  # 11
    print(abs(0))  # 0
    print(abs(11))  # 11
    
    # 如果是空或布尔值为真则返回True
    print(all(''))  # True
    print(all([]))  # True
    print(all([11, 22, 333, 0]))  # False
    
    # 只要有一个值的布尔值为真就返回True
    print(any(''))  # False
    print(any([]))  # False
    print(any([0, None, '', 1]))  # True
    print(any([0, None, '']))  # False
    
    # ASCⅡ表:65-90 A-Z
    print(chr(65))  # 数字->字母A
    print(ord('A'))  # 字母->数字65
    print(chr(90))  # Z
    
    # 进制转换
    print(bin(11))  # 十进制->二进制 0b1011
    print(oct(11))  # 十进制->八进制 0o13
    print(hex(11))  # 十进制->十六进制 0xb
    
    # 工厂函数
    int
    float
    str
    list
    tuple
    dict
    set
    bool
    bytes
    
    # 查看对象是否可调用
    print(callable(len))  # True
    
    # 面向对象重点
    classmethod
    staticmethod
    setattr
    getattr
    delattr
    hasattr
    dir
    exec
    
    l = eval("[1, 2, 3]")
    print(l[0])  # 1
    with 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
    
  • 相关阅读:
    为什么要使用MQ消息中间件?
    趣图:这是招聘超神级别的程序员?
    基于redis的分布式锁的分析与实践
    我的java问题排查工具单
    趣图:看到这些窗户,我想插上几根网线
    SpringBoot+MyBatis+MySQL读写分离(实例)
    IntelliJ IDEA 常用快捷键
    ex3 多分类和神经网络
    9、神经网络的学习
    神经网络--反向传播详细推导过程
  • 原文地址:https://www.cnblogs.com/caojiaxin/p/14099454.html
Copyright © 2020-2023  润新知