• Python:Day16 闭包、装饰器


    def outer():
        x = 10
        def inner():  #条件一、inner就是一个内部函数
            print(x)  #条件二、引用外部作用域的一个变量,因为x在函数外部的,所以是外部作用域的变量
        return inner  #结论:内部函数inner就是一个闭包
    
    inner()     #局部变量,全局无法调用


    闭包(closure)是函数式编程的重要的语法结构

    定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

    闭包可以脱离环境在外部调用 

    装饰器(函数)

    装饰器的作用就是给功能函数添加新功能。

    import time
    
    def show_time(func):
        def inner():
            start_time = time.time()
            func()
            time.sleep(1)
            end_time = time.time()
            print('spend time %s'%(end_time-start_time))
        return inner
    
    @show_time    #这条命令等价于 foo = show_time(foo),注意:这个show_time后面并没有加(),虽然看似没被调用,其实,show_time这个函数已经执行了。
    def foo():
        print('foo......')
    
    foo()

    注意:1、装饰器要放在@上面,不然会报错。
               2、装饰器一般用两层函数,外面一层用于将变量确定下来,里面一层函数执行整个功能。
               3、其实一层函数也能为装饰器,只不过没有参数做为变动,程序就被写死了,不能做为公共接口。

    带有参数的功能函数的装饰器:

    import time
    
    def show_time(func):
        def inner(*args):  #首先这里要带参数,以便将参数传进功能函数
            start = time.time()
            func(*args)  #这里面也要带参数,用来接收参数
            end = time.time()
            print('spend time %s'%(end-start))
        return inner
    
    @show_time
    def add(*args):
        total = 0
        for i in args:
            total += i
        print(total)
    
    add(1,2,3,4)

    装饰器参数:

    import time
    
    def logger(flag):
        def show_time(func):
            def inner():
                start_time = time.time()
                func()
                time.sleep(1)
                end_time = time.time()
                print('spend time %s'%(end_time-start_time))
                if flag == 'true':
                    print('日志记录')
            return inner
        return show_time
    
    @logger('true')     #这里必须要加括号加参数,这才代表是一个装饰器参数,不然系统会执行foo=logger(foo),这样到show的时候就没有参数然后报错。
    def foo():
        print('foo.....')
    
    foo()

    以上面的代码为例,带参数的装饰器其实是先执行logger("true")这个函数,这个函数执行返回show_time,这时上面其实就是@show_time,而@后面加一个函数名,就是将下面的函数名当参数传入到这个show_time()这个函数里面去,然后去执行,虽然没有调用,其实这里面也已执行了两次函数了。

  • 相关阅读:
    Vue(知识讲解)
    爬虫框架:scrapy
    爬虫性能相关
    MongoDB
    Beautifulsoup模块
    selenium模块
    requests模块
    爬虫(集锦)
    爬虫目录
    Flask目录
  • 原文地址:https://www.cnblogs.com/sq5288/p/8383424.html
Copyright © 2020-2023  润新知