• 十、装饰器,闭包


    一、闭包函数:
    1.定义在函数内部的函数
    2.内部函数引用了外部函数名称空间作用域的名字
    主要满足上面的两点都叫做闭包函数

    *****一定要在内部函数一定要有调用外部函数名称才能称为闭包

    1.闭包函数
    1.闭:定义在函数内部的函数
    2.包:内部函数引用了外部函数作用域的名字
    # def outter():
    #     x = 111
    #     def inner():
    #         print(x)
    #     return inner
    # res = outter()  # res就是inner函数内存地址
    #
    # def func():
    #     x = 333
    #     res()
    # func()
    1.inner()函数调用了外部函数outter()x的值。
    2.inner()函数在outter()函数里面
    这就是闭包

    函数在定义阶段名字的查找顺序就已经固定死了
    不会因为函数调用位置的变化而改变!!!

    小爬虫,
    爬虫的本质就是爬取页面的html代码
    从中获取到你想要的数据(url链接地址)
    有了链接之后 你就可以顺着这个链接将所有的页面资源全部爬取下来

    # 第一个直接给函数传参
    url1 = 'https://www.baidu.com'
    url2 = '...'
    def my_get(url):
        response = requests.get(url)
        if response.status_code == 200:
            print(len(response.text))
    
    my_get(url1)
    my_get(url1)
    my_get(url1)
    my_get('https://www.baidu.com')
    my_get('https://www.baidu.com')
    my_get('https://www.baidu.com')
    View Code

    二.装饰器的简介

    装饰器:
    器:就是一个工具
    装饰:给被装饰对象添加新的功能
    开放封闭原则:
    开放:对扩展开放
    封闭:对修改封闭

    装饰器(可调用对象)必须遵循的两个原则:
    1.不改变被装饰对象源代码
    2.不改变被装饰对象(可调用对象)调用方式
    1.统计index函数执行的时间
    """
    import time
    def index():
        time.sleep(3)
        print('澳门最大线上赌场开业啦 性感tank在线发牌!')
    
    start = time.time() #计时开始
    index()
    end = time.time()  # 计时结束
    print('index run time:%s'%(end-start))
    # 2.如果引用装饰器
    import time
    
    
    def index():
        time.sleep(3)
        print("上海真的好好玩!")
    
    
    def outter(func):
        def get_time():
            start = time.time()
            func()
            end = time.time()
            print("执行这个函数所花的时间%s"%(start-end))
        return get_time
    
    
    index = outter(index)  # 把函数当作参数传进去,index=func,res=get_time,
                          #  在不改变函数的情况下,添加功能
    index()
    # index指向get_time函数的内存地址然后去执行
    # 3.有参数的装饰器
    # 函数可以接收任意数量的参数
    # 需求计算login函数运行时间
    import time
    
    
    def login(name):
        time.sleep(3)
        print(f"{name}是个二货")
        return "login"
    
    
    # 弄个闭包函数
    def outter(func):
        def get_time(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            end = time.time()
            print(f"函数运行的时间:{start - end}")
            return res
    
        return get_time
    login = outter(login)
    res2=login("鸡哥")
    print(res2)
    # 在装饰的过程中既把函数login运行时间测试出来,又运行login函数并得到login返回值

    三.装饰器语法糖

    # 语法糖在书写的时候应该与被装饰对象紧紧挨着 
    # 两者之间不要有空格
    import time
    
    
    
    # 弄个闭包函数
    def outter(func):
        def get_time(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            end = time.time()
            print(f"函数运行的时间:{start - end}")
            return res
    
        return get_time
    @outter
    def login(name):
        time.sleep(3)
        print(f"{name}是个二货")
        return "login"
    # 在login函数上面加上@outter,是装饰login函数增添outter函数功能,注意加装饰器一定是先定义后加装
    #并且@outter  相当于login = outter(login)的省略,下面 只需要执行login函数就可以了
    res = login("坦克")
    print(res)

    四.装饰器的模板:

    # 1.装饰器的模板
    
    def outter(func):
        def inner(*args,**kwargs):
            print("执行前的代码")
            res = func(*args,**kwargs)
            print("执行后的代码")
            return res
        return inner
    def index():
        pass
    
    index=outter(index)
    res1 =index(*args,**kwargs)
    print(res1)
    2.多层装饰器模板   
     from functools import wraps
        def outter(func):
            @wraps(func)
            def inner(*args,**kwargs):  # * **在形参中使用
                # 执行被装饰函数之前你可以做的操作
                res = func(*args,**kwargs)  # * **在实参中使用
                # 执行被装饰函数之后你可以做到操作
                return res
            return inner
    
        @outter
        def index(username,*args,**kwargs):
            """index注释"""
            pass
        print(index)

    五.装饰器修复

    # 装饰器修复术
    from functools import wraps  # 导入模块functools  wraps功能
    def outter(func):
        @wraps(func)  # 装饰器修复,返回是原来函数内存地址
        def inner(*args,**kwargs):
            # 执行前的代码
            res = func(*args,**kwargs)
            # 执行后的代码
            return res
        return inner
    @outter # index=outter(index)
    def index():
        pass
    res1=index(*args,**kwargs)
    print(res1)
     #返回是原来函数内存地址

    六.多层装饰器

     1 def outter1(func1):
     2     print('加载了outter1')
     3 
     4     def wrapper1(*args, **kwargs):
     5         print('执行了wrapper1')
     6         res1 = func1(*args, **kwargs)
     7         return res1
     8 
     9     return wrapper1
    10 
    11 
    12 def outter2(func2):
    13     print('加载了outter2')
    14 
    15     def wrapper2(*args, **kwargs):
    16         print('执行了wrapper2')
    17         res2 = func2(*args, **kwargs)
    18         return res2
    19 
    20     return wrapper2
    21 
    22 
    23 def outter3(func3):
    24     print('加载了outter3')
    25 
    26     def wrapper3(*args, **kwargs):
    27         print('执行了wrapper3')
    28         res3 = func3(*args, **kwargs)
    29         return res3
    30 
    31     return wrapper3
    32 
    33 
    34 @outter1  # index = outter1(wapper2)
    35 @outter2  # wrapper2 = outter2(wrapper3)
    36 @outter3  # wrapper3 = outter3(最原始的index函数内存地址)  
    37 # 开始:index=outter(index)
    38 def index():
    39     print('from index')
    40 
    41 
    42 index()
    43 # 装饰器在装饰的时候  顺序从下往上
    44 # 装饰器在执行的时候  顺序从上往下
    45 """
    46 加载了outter3
    47 加载了outter2
    48 加载了outter1
    49 
    50 执行了wrapper1
    51 执行了wrapper2
    52 执行了wrapper3
    53 from index
    54 """
    View Code

     



  • 相关阅读:
    Gates entitled as knight
    the next generation Office
    Beautiful songs
    一则比较搞笑的新闻:【人才】微软招募英才 机会不容错过
    About cmt lint tools
    Alpha's blog open !
    抱歉!
    新闻:IBM的新工具CHIPHOPPER! 一套能够极大扩展Linux应用范围的新工具、新资源和新软件
    读书笔记:Thinking in Java (一)
    The best coders are:/什么是最牛的程序员
  • 原文地址:https://www.cnblogs.com/wukai66/p/11177256.html
Copyright © 2020-2023  润新知