zoukankan      html  css  js  c++  java
  • 函数(四)——装饰器

    今日内容概要:

    一、巩固复习

    二、装饰器(掌握)

    内容详解:

    一、巩固复习

    1、一定要熟记的格式:

    def register(name, age,gender="male"):
        print(name, age, gender)
    
    def wrapper(*args,**kwargs):
        index(*args,**kwargs)
    
    #根据register,wrapper内必须传三个实参,鉴于形参gender已定义,可以默认不传也可传值
    wrapper(???)

    2、函数体传参的两种方式

     (1)直接传参(直接通过参数的形式为函数体传)

    def func(x):
        print(x)
    
    func(1)
    func(2)
    func(3)

     (2)闭包传参(把它想要的参数值包给它)

    def outter(x):
        # x = 1
        def func():
            print(x)
        return func
    
    f1=outter(1)
    f2=outter(2)

    3、基于函数对象的概念优雅地取代if判断多分支

    def foo():
        print('foo')
    
    def bar():
        print('bar')
    
    dic={
        'foo':foo,
        'bar':bar,
    }
    while True:
        choice=input('>>: ').strip()
        if choice in dic:
            dic[choice]()

    4、名称空间的名字查找顺序

    局部-》外层套的局部-》外层套的局部-》....-》全局-》内置

    5、强调强调强调

    名称空间的"嵌套关系"是函数定义阶段、也就是检测语法的时候就确定的,与调用为无关

    6、global的作用

    声明变量是来自全局的,如果要修改必须在全局找变量赋值,不能在局部,找不到就报错

    7、nonlocal的作用

    声明变量是来自局部的,如果要修改必须在自己函数的外一层找,找不到再在外一层找,但不能在全局或自己函数内找,找不到就报错

    8、闭包函数=函数对象+函数嵌套定义+名称空间与作用域

    基本模板:
    def outter():
       x=123
       def inner():
           x
       return inner # 函数是第一等公民、第一类对象
    
    res=outter()
    res()

     

    二、装饰器

    1、什么是装饰器
    器指的是工具/功能
    装饰指的是为被装饰对象添加额外的功能

    大白话:定义装饰器就是定义了一个函数,该函数就是用来为其他函数添加额外的功能的

    2、为何要用装饰器
    程序的开发需要遵循一个原则:开放封闭原则
    开放:指的是对拓展功能开放
    封闭:指的是对修改源代码封闭

    装饰器就是在不修改被装饰对象源代码以及调用方式的前提下为被装饰对象添加上新功能

    3、如何用装饰器
    # 1、装饰器初探
    import time
    
    def index(x, y):
        time.sleep(3)
        print('index===>', x, y)
    
    
    # index(1,2)
    
    
    def home(name):
        time.sleep(2)
        print('home====>', name)
    
    
    # home("egon")
    
    def outter():
        x = index
    
        def wrapper(a, b):
            start_time = time.time()
            x(a, b)
            stop_time = time.time()
            print("run time is :%s" % (stop_time - start_time))
    
        return wrapper  # 千万不要加括号
    
    
    index = outter()  # f=wrapper
    
    index(1, 2)  # wrapper()
    # 1、装饰器初探
    # 2、装饰器改进1
    
    import time
    
    def index(x, y):
        time.sleep(3)
        print('index===>', x, y)
    
    def home(name):
        time.sleep(2)
        print('home====>', name)
    
    def outter(x):
        # x = home
        def wrapper(*args,**kargs):
            start_time = time.time()
            x(*args,**kargs) # x("egon")
            stop_time = time.time()
            print("run time is :%s" % (stop_time - start_time))
        return wrapper  # 千万不要加括号
    
    index = outter(index)  # index=wrapper
    home = outter(home)  # home=wrapper
    
    
    index(1, 2)  # wrapper(1,2)
    home("egon")  # wrapper("egon")
    # 2、装饰器改进1
    # 3、装饰器改进2
    
    import time
    
    
    def index(x, y):
        time.sleep(3)
        print('index===>', x, y)
        return 456
    
    def home(name):
        time.sleep(2)
        print('home====>', name)
        return 123
    
    
    def outter(x):
        # x = home
        def wrapper(*args, **kargs):
            start_time = time.time()
            res = x(*args, **kargs)  # x("egon")
            stop_time = time.time()
            print("run time is :%s" % (stop_time - start_time))
            return res
        return wrapper  # 千万不要加括号
    
    index = outter(index)  # index=wrapper
    home = outter(home)  # home=wrapper
    
    res1 = index(1, 2)  # wrapper(1,2)
    res2 = home("egon")  # wrapper("egon")
    print("====>",res1)
    print("====>",res2)
    # 3、装饰器改进2
    # 4、语法糖
    
    import time
    
    def outter(x):
        # x = home
        def wrapper(*args, **kargs):
            start_time = time.time()
            res = x(*args, **kargs)  # x("egon")
            stop_time = time.time()
            print("run time is :%s" % (stop_time - start_time))
            return res
    
        return wrapper  # 千万不要加括号
    
    
    @outter  # index = outter(index)  # index=wrapper
    def index(x, y):
        time.sleep(3)
        print('index===>', x, y)
        return 456
    
    
    @outter  # home = outter(home)  # home=wrapper
    def home(name):
        time.sleep(2)
        print('home====>', name)
        return 123
    
    
    res1 = index(1, 2)  # wrapper(1,2)
    res2 = home("egon")  # wrapper("egon")
    print("====>", res1)
    print("====>", res2)
    # 4、语法糖
    # 5、装饰器的模板
    
    def outter(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    
    def timmer(func):
        def wrapper(*args, **kwargs):
            start=time.time()
            res = func(*args, **kwargs)
            stop=time.time()
            print(stop -start)
            return res
        return wrapper
    
    def auth(func):
        def wrapper(*args, **kwargs):
            name = input("请输入您的账号:").strip()
            pwd = input("请输入您的账号:").strip()
            if name == "egon" and pwd == "123":
                print('登录成功')
                res = func(*args, **kwargs)
                return res
            else:
                print("账号密码错误")
        return wrapper
    
    @auth
    def index(x, y):
        time.sleep(1)
        print('index===>', x, y)
        return 456
    
    @auth
    def home(name):
        time.sleep(0.5)
        print('home====>', name)
        return 123
    
    index(1,2)
    home("egon")
    # 5、装饰器的模板
    # 6、wraps
    
    from functools import wraps
    
    def timmer(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start=time.time()
            res = func(*args, **kwargs)
            stop=time.time()
            print(stop -start)
            return res
        # wrapper.__name__ = func.__name__
        # wrapper.__doc__ = func.__doc__
        return wrapper
    
    @timmer # index=timmer(index) # index=wrapper
    def index(x, y):
        """
        这是index函数的文档注释
        """
        time.sleep(1)
        print('index===>', x, y)
        return 456
    
    
    # index(1,2)
    # print(index.__name__)
    help(index)
    # 6、wraps装饰器

    语法糖的作用:写在被装饰函数正上方,用 @+装饰器函数名outter ,调用一下装饰器函数outter ,把被装饰函数index传进来,将返回值wrapper覆盖给原函数

      4、无参装饰器(两层)

    import time
    def timmer(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
        return wrapper
    
    @timmer
    def foo():
        time.sleep(3)
        print('from foo')
    foo()
    #无参装饰器

      5、有参装饰器(三层)

    def auth(driver='file'):
        def auth2(func):
            def wrapper(*args,**kwargs):
                name=input("user: ")
                pwd=input("pwd: ")
    
                if driver == 'file':
                    if name == 'egon' and pwd == '123':
                        print('login successful')
                        res=func(*args,**kwargs)
                        return res
                elif driver == 'ldap':
                    print('ldap')
            return wrapper
        return auth2
    
    @auth(driver='file')
    def foo(name):
        print(name)
    
    foo('egon')
    #有参装饰器

      6、最完整的装饰器模板

    #必须要牢记!!!

    from functools import wraps #这一行和@wraps(func)可以不加,执行后只是少了文本注释 def outter(func): #func指的就是被装饰对象 @wraps(func) def wrapper(*args, **kwargs): #wrapper就是给被装饰对象添加功能 res = func(*args, **kwargs) return res return wrapper #返回的wrapper一定不要加括号
  • 相关阅读:
    原子变量AtomicInteger
    8.2.2.2 Speed of UPDATE Statements 加速UPDATE语句:
    8.2.2 Optimizing DML Statements 优化DML 语句:
    CSS3中-moz、-ms、-webkit和-o分别代表什么意思
    8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:
    java.lang.IllegalArgumentException: Negative time
    8.2.1.17 DISTINCT Optimization
    Python基本语法_函数_参数的多类型传值
    Python基本语法_函数_参数的多类型传值
    8.2.1.16 GROUP BY Optimization
  • 原文地址:https://www.cnblogs.com/guojieying/p/13160107.html
Copyright © 2011-2022 走看看