python day16:装饰器

  • Post author:
  • Post category:python


闭包

定义:如果在一个内部函数里,对再外部作用域的变量进行引用,那么

内部函数

就被认为是一个

闭包

条件:1.是一个内部函数    2.函数内有外部环境的一个变量

效果:脱离环境在外部调用变量

def outer():
    x=10
    def inner():
        print(x)
    return inner
f=outer()
f()

输出结果为10

装饰器

我们设想一个场景,你已经写好了一个函数


def f():
    print('this is a function')

f()

但是你的boss让你再增加一个能输出每个函数运算所花时间的功能

你该怎么办呢?

很显然以下方法很简单

import time
def f():
    start=time.time()
    print('this is a function')
    end=time.time()
    print(end-start)
f()

但如果你要修改许多许多函数,一个一个改肯定不现实

所以我们就想到了用函数修改函数

import time
def f():

    print('this is a function')

def modify(f):
    start=time.time()
    f()
    end=time.time()
    print(end-start)
modify(f)

然而问题又来了,好端端的函数f又变成需要modify(f)才能执行,为什么不能把更改过后的函数直接赋给原来的函数呢?

import time
def f():

    print('this is a function')

def modify(f):
    start=time.time()
    f()
    end=time.time()
    print(end-start)
f=modify(f)

问题又双叒叕来了,你确定最后的f是一个函数吗?


我们之前说过了闭包的特性,在此我们可以用闭包来解决这个问题

import time
def f():

    print('this is a function')

def modify(f):
    def inner():
        start=time.time()
        f()
        end=time.time()
        print(end-start)
    return inner
f=modify(f)

这样f被修改成一个保有原来功能,并添加了能输出每个函数运算所花时间的功能的函数


这个modify函数便是一个装饰器

也可以这么表达

import time

def modify(f):
    def inner():
        start=time.time()
        f()
        end=time.time()
        print(end-start)
    return inner

@modify

def f():
    print('this is a function')

@modify就是把modify函数作为装饰器修改f函数,其意义和在最后 f=modify(f) 是一样的

可以给功能函数加参数

import time

def modify(f):
    def inner(*a):
        start=time.time()
        f()
        end=time.time()
        print(end-start)
    return inner

@modify

def f(*a):
    sum=0
    for i in a:
        sum+=i
    print(i)

也可以给装饰器加参数

import time
def one(judge):
    def modify(f):
        def inner(*a):
            start=time.time()
            f()
            end=time.time()
            if judge==True
                print(end-start)
        return inner
    return modify

@one(True)

def f(*a):
    sum=0
    for i in a:
        sum+=i
    print(i)

对于想显示运行时间,可以@one(True),不想显示可以@one(False),增加了装饰器的可用性



版权声明:本文为Dovhkin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。