zoukankan      html  css  js  c++  java
  • 装饰器

    装饰器

    定义

    在不改变函数的源码和调用方式的情况下,给函数加功能

    装饰器本质就是一个函数A,装饰的对象也是一个函数B,用一个函数A去装饰一个函数B

    1. 不改变函数B的调用方式
    2. 不改变函数B的源代码

    分类

    双层装饰器

    例如,函数world是一个完整的功能函数,想要给world函数增加一个程序运行时长的功能,但不改变world函数的源码和调用方式,如何实现呢?

    这样,我们就可以用到装饰器了:

    import time
    
    def time_world(func): # func是真正的world
        """装饰函数"""
        def add():
            # 增加功能部分
            t1 = time.time()  # func() == world()
            func()
            t2 = time.time()
            print(t2 - t1)
        return add
    
    def world():
        """被装饰函数"""
        print('hello world!')
        time.sleep(1)
    world = time_world(time)
    world() # 调用方式不变world(),实际是调用add()
    
    """
    用语法糖来调用更简单
    @time_world
    def world():
        """被装饰函数"""
        print('hello world!')
        time.sleep(1)
    world()
    """
    

    三层装饰器

    三层装饰器就是给双层装饰器加参数

    例如,给shopping函数增加登录功能,并且传入登录方式变量,如果登录方式是file,则登录成功,如果是db,则登录非法。

    因为涉及到传值,双层装饰器显然实现较为困难,因此,引入三层装饰器:

    def three(gen):
        def login(func):
            def inner(*args,**kwargs): # 接收shopping传的所有值
                if gen == 'file':
                    name = input('name:')
                    pwd = input('password:')
                    # 假定name,pwd固定
                    if name == 'wzh' and pwd == '123':
                        print('success!')
                        res = func(*args,**kwargs)
                        return res
                    else:
                        print('default')
                 elif gen == 'db':
                    print('登录非法!')
    		return inner
        return login
    
    @three('file')
    def shopping():
        print('shopping!')
        
    shopping()         
    

    双层语法糖

    执行顺序相关

    # 双层语法糖
    def outer1(func):
        def inner(*args,**kwargs):  # 接收index里的参数
            """功能模块"""
            print('----------------')
            res = func(*args,**kwargs)
            print('----------------')
            return res   # 返回index里的参数
        return inner
    def outer2(func):
        def inner(*args,**kwargs):  # 接收index里的参数
            """功能模块"""
            print('****************')
            res = func(*args,**kwargs)
            print('****************')
            return res   # 返回index里的参数
        return inner
    
    @outer1
    @outer2
    def f():
        print('success')
    f()
    
    """
    ----------------
    ****************
    ssss
    ****************
    ----------------
    """
    

    装饰器模板(重要)

    # 双层装饰器
    def two(func):
        def two_inner(*args,**kwargs):
            """功能模块"""
            res = func(*args,**kwargs)
    		return res
        return inner
    @two
    def f():
        pass
    f()
    
    # 三层装饰器
    def three(value):
        def two(func):
            def innere(*args,**kwargs):
                """功能模块"""
                print(value)
                res = func(*args,**kwargs)
                return res
            return inner
        return two
    @three('shabi')
    def f():
        pass
    f()
    
  • 相关阅读:
    MPLS TE 知识要点
    MPLS TE CBR仲裁法则仲裁法则
    MPLS TE CBR仲裁法则Administrate-weight
    MPLS TE CBR仲裁法则亲和值及接口属性标记
    影响CBR为TE选择tunnel建立路径的因素
    Micro LED 技术详谈
    准分子激光概述
    激光讨论
    PI膜热作用机理
    激光作用的物理过程
  • 原文地址:https://www.cnblogs.com/dadazunzhe/p/11340891.html
Copyright © 2011-2022 走看看