• day12 装饰器


    作业讲解和昨日回顾

    2、动态参数*args  ,**kwargs:位置参数,*args,默认参数,**kwargs

         命名空间和作用域

         作用域链

         函数名是第一类对象的概念

    二、新内容:闭包

    1、闭包的定义:闭包必须是嵌套函数,内部函数引用外部函数的变量

    def f1():
        b=123
        def f2():
            print(b)

     2、例子:用__closure__检测是不是闭包

    def fl():
        a=1
        def f2():
            def f3():
                print(a)
            f3()
            print("f3:",f3.__closure__)
        f2()
        print("f2:",f2.__closure__)
    fl()
    
    # 1
    # f3: (<cell at 0x00000000027A85E8: int object at 0x00000000655B60E0>,)
    # f2: (<cell at 0x00000000027A85E8: int object at 0x00000000655B60E0>,)

    3、外面调用里面的函数,是闭包的常用状态

    def f1(b):
        def f2():
            print(b)
        return f2
    
    ff = f1("bbb")
    ff()
    #bbb
    详细步骤:
    
    def f1():
        b=10
        def f2():
            return b
        ret_b=f2()
        return ret_b
    ret_b=f1()
    print(ret_b)
    简写
    def f1():    #从内部返回一个值到全局
        b=10
        def f2():
            return b
        return f2()
    print(f1())

    4、在爬虫中应用闭包

    from urllib.request import urlopen
    def get_url(url):
        def readl():
            ret=urlopen(url).read()
            print(ret)
        return readl
    read_func=get_url("https://i.cnblogs.com/EditPosts.aspx?opt=1")
    read_func()

    三:装饰器

    装饰器的作用:在不改变函数的调用方式的情况下,给函数的前后添加新的功能

    1、关于时间:计算运行时间差

    import time        #模块
    start_time=time.time()
    time.sleep(1)
    end_time=time.time()
    print("======%s======"%(end_time-start_time))

    利用闭包计算时间差

    import time
    def timmer(func):
        def inner():
            start_time=time.time()
            time.sleep(0.1)
            func()
            end_time=time.time()
            print("===%s==="%(end_time-start_time))
        return inner
    def func():
        print("dajiahao")
    func=timmer(func)
    func()
    # dajiahao
    # ===0.1000056266784668===
     

    2、重要模板说明

    import time
    def timmer(qqxing):     #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner():        #在装饰器中需要定义一个内部的函数
            print("调用func之前")
            qqxing()                #被装饰的函数,并且要执行
            print("调用func之后")
        return inner                #将内部函数的名字返回
    
    def func():
        print("dajiahao")
        
    func=timmer(func)
    func()

    3、装饰器是闭包的典型应用

       语法糖的应用

    import time
    def timmer(qqxing):     #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner():        #在装饰器中需要定义一个内部的函数
            print("调用func之前")
            qqxing()                #被装饰的函数,并且要执行
            print("调用func之后")
        return inner                #将内部函数的名字返回
    
    @timmer           #语法糖 func=timmer(func)
    def func():
        print("dajiahao")
    
    func()
    #调用func之前
    #dajiahao
    #调用func之后

    4、完整的装饰器例子

    import time
    def timmer(qqxing):     #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner(name):        #在装饰器中需要定义一个内部的函数
            print("调用func之前")
            qqxing(name)                #被装饰的函数,并且要执行
            print("调用func之后")
        return inner                #将内部函数的名字返回
    
    @timmer           #语法糖 func=timmer(func)
    def func(name):
        print("%s你好"%(name))
    
    func("虫虫")
    # 调用func之前
    # 虫虫你好
    # 调用func之后

    5、装饰器的固定结构

    # 装饰器的固定结构
    def wrapper(func):               #timmer 是装饰器的名字,传入的参数就是被装饰的函数
        def inner(*args,**kwargs):      #在装饰器中需要定义一个内部函数
            """被装饰函数之前添加的代码"""
            ret=func(*args,**kwargs)    #被装饰器的函数,并且要执行
            # """被装饰函数之后添加的代码"""
            return ret
        return inner                    #将内部函数的名字返回

    四、装饰器的开放封闭原则

    概念:开放封闭原则

    开放:  对扩展是开放的

    封闭:对修改是封闭的

    装饰器:开放封闭原则

    1、例题:利用装饰器设置登录一次的程序

    flag=False
    def login(func):
        def inner(*args,**kwargs):
            global  flag
            if flag==False:
                username=input("用户名:")
                password=input("密码:")
                if username=="alex" and password=="someboday":
                    print("登录成功")
                    flag=True
            if flag==True:
                ret=func(*args,**kwargs)
                return ret
        return inner
    @login
    def art():
        print("欢迎来到文章页")
    @login
    def dar():
        print("欢迎来到日志页")
    art()
    dar()

    记录日志:

    def log(func):
        def inner(*args,**kwargs):
            print("你要调用%s函数了"%func.__name__)
            ret=func(*args,**kwargs)
            return  ret
        return inner
    @log
    def f1():
        print("f1")
    @log
    def f2():
        print("f2")
    f1()
    f2()
  • 相关阅读:
    接口和抽象类的异同点
    实体对象间传值克隆
    什么是反射&反射的8个类的用法
    ERP中反射的两个实例
    基础02 Java 跨平台原理
    基础01 dos命令
    lists删除
    多字段 java对象排序
    Java对象排序
    MySQL表中数据的迁移
  • 原文地址:https://www.cnblogs.com/number1994/p/7941399.html
Copyright © 2020-2023  润新知