搬马

导航

 

 

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()这个函数里面去,然后去执行,虽然没有调用,其实这里面也已执行了两次函数了。

posted on 2018-01-30 08:17  搬马  阅读(89)  评论(0编辑  收藏  举报