Python 装饰器

python学习网 2018-04-11 16:59:03

我们首先了解下什么是闭包

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

def outer():
    a = 8
    def inner():             # 条件一: inner就是内部函数
        print(a)             # 条件二:  外部环境的一个变量
    return inner             # 结论:内部函数 inner 就是一个闭包

f = outer()
f()

运行结果:
8

装饰器

import time


def foo():
    print('foo....')
    time.sleep(2)


def bar():
    print('bar....')
    time.sleep(2)


def show_time(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print('spend %s' % (end - start))

    return  inner

foo = show_time(foo)
foo()

运行结果:
foo....
spend 2.0003552436828613

@符号是 python 装饰器的语法,在定义函数的时候使用,避免再一次赋值操作

import time


def show_time(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print('spend %s' % (end - start))

    return inner

@show_time                 # bar = show_time(bar)
def bar():
    print('bar....')
    time.sleep(2)

bar()

运行结果:
bar....
spend 2.0004019737243652


执行 bar 函数实际上是执行 inner 函数的内容

带有未命名的变量参数的装饰器

import time
def show_time(func):
    def inner(*args):
        start = time.time()
        func(*args)
        end = time.time()
        print('spend %s' % (end - start))

    return inner

@show_time
def add(*args):
    sums = 0
    for i in args:
        sums += i
    print(sums)
    time.sleep(2)

add(1, 2, 3, 4, 5)

运行结果:
15
spend 2.0084943771362305

功能函数带参数

import time
def logger(flag):          # 把 flag 传入 inner 函数中 
    def show_time(func):
        def inner(*args):
            start = time.time()
            func(*args)
            end = time.time()
            print('spend %s' % (end - start))
            if flag == 'true':
                print("write log ....")

        return inner
    return  show_time

@logger('true')           # 这里调用 logger 函数 return show_time 实际上是调用了 @show_time
def add(*args):
    sums = 0
    for i in args:
        sums += i
    print(sums)
    time.sleep(2)

add(1, 2, 3, 4, 5)

运行结果:
15
spend 2.000865936279297
write log ....
阅读(722) 评论(0)