zoukankan      html  css  js  c++  java
  • 闭包函数及装饰器

    闭包函数及装饰器

    一、闭包函数

    1.1 函数传参的方式一

    def func(x):
        print(x)
    
    func(1)
    func(1)
    func(1)
    -------------------------------------------------------------
    1
    1
    1
    

    1.2 函数传参的方式二

    闭包函数,把变量和函数一起包起来,下次要用直接调用

    #这样传就不会每一次传参的时候都输入
    def outter(x):
        x = 1
    
        def inner():
            print(x)
        return inner
    
    f = outter(1)
    f()
    f()
    f()
    ---------------------------------------------------------
    1
    1
    1
    

    让我们再看一个利用闭包函数爬取网站的例子吧!

    import requests
    
    def func(url):
        def get_res():
            response = requests.get(url)
            print({url})
        return get_res
    
    baidu = func('https://www.baidu.com')
    
    baidu()
    baidu()
    -----------------------------------------------------------
    {'https://www.baidu.com'}
    {'https://www.baidu.com'}
    

    二、装饰器

    2.1 什么是装饰器

    装饰器:装饰的工具(函数),这个函数有装饰的作用

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

    2.2 装饰器遵循的原则

    1. 不改变函数B的调用方式

    2. 不改变函数B的源代码

    def A():
        """装饰器"""
        pass
    
    def B():
        """被装饰的对象"""
        pass
    B()
    

    2.3 装饰器举例

    打印函数运行的时间

    # 2.3.1 改变了函数体代码,没改变调用方式(不是装饰器,没有遵循装饰器原则)
    import time
    
    def index():
        start = time.time()
        print('您好')
        time.sleep(1)
        end = time.time()
        print(end-start)
        
    index()
    ----------------------------------------------------------
    您好
    1.0013189315795898
    
    # 2.3.2 没改变调用方式,也没改变源码,但是不通用(不是装饰器,没有遵循装饰器原则)
    import time 
    def index():
        '''被装饰的函数'''
        print('hello')
    def index1():
        print('hello1')
        
        start = time.time()
        index()
        time.sleep(1)
        end = time.time()
        print(end-start)
        
        start = time.time()
        index1()
        time.sleep(1)
        end = time.time()
        print(end-start)
    -----------------------------------------------------------
    hello
    1.0003104209899902
    hello1
    1.000321388244629
    #每次调用的时候都得运行一遍,真的很麻烦
    
    # 2.3.3  真正的装饰器
    import time
    def index():
        print('您好啊!')
        time.sleep(1)
    
    def deco(func):    # func = 真正的index
        '''装饰器'''
        def f1():    #重新创建的index
            start = time.time()
            func()      #真正的index
            end = time.time()
            print(end-start)
        return f1
    
    index = deco(index)
    index()     #f1
    

    2.4 三层装饰器

    #利用装饰器写一个装饰器
    def auth(engine):
        def login(func):
            def inner(*args,**kwargs):
                #登录功能
                if engine =='file':
                    username = input('username:')
                    pwd = input('pwd:')
                    if username =='jiayi'and pwd =='123':
                        print('登录成功')
                        res = func(*args,**kwargs)  #shopping()
    
                        print('登录失败')
    
                elif engine =='db':
                    print('账号来自于数据库,非法请求')
    
            return inner
        return login
    @auth('db')
    def shopping():
        print('shopping')
    shopping()
    -------------------------------------------------------------------------
    账号来自于数据库,非法请求
    

    2.5 装饰器模板

    2.5.1 双层装饰器

    def outter(func):
        def wrapper(*args.**kwargs):  #wrapper是未来要运行的函数
            #加功能
            res = func(*args,**kwargs)  #func是被装饰的函数
            return res
        return wrapper
    @outter
    def shopping():
        print('shopping')
    

    2.5.2 三层装饰器

    # 三层装饰器:给双层装饰器加参数
    def sanceng (engine):
        def outter(func):
            def wrapper(*args,**kwargs):  # wrapper是未来要运行的函数
                #加功能
                print(engine)
                res = func(*args,**kwargs)  #func是被装饰的函数
                return  res
            return wrapper
        return outter
    
    @sanceng('db')
    def shopping():
        print('shopping')
    
  • 相关阅读:
    凭什么要用面向对象编程(补充)
    一篇面试题文章引发的“争议”
    伍迷创意随想集 之 杯具拥有个性,个性成就杯具
    Apple Mac OS X每日一技巧016:MacBook电源线如何缠绕
    Apple Mac OS X每日一技巧008:快速调整/删除菜单栏上的图标
    《C#妹妹和ObjectiveC阿姨对话录》(05)自动释放池--拆迁队的外援
    Apple Mac OS X每日一技巧005:Photo Booth把你的Mac当成照相机
    Apple Mac OS X每日一技巧010:查看本机的版本、版号和序列号
    Apple Mac OS X每日一技巧009:option键和菜单栏的系统图标
    Apple Mac OS X每日一技巧004:抓屏那点事(截屏/抓图/截图)
  • 原文地址:https://www.cnblogs.com/yanjiayi098-001/p/11340438.html
Copyright © 2011-2022 走看看