码迷,mamicode.com
首页 > 其他好文 > 详细

装饰器

时间:2018-12-14 23:30:09      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:内部函数   ack   函数名   str   func   无法   fun   turn   UNC   

装饰器:本质就是函数,功能是为其他函数添加附加功能。

两个原则:

1.不修改被修饰函数的源代码

2.不修改被修饰函数的调用方式

 一个栗子

def test():
    res = 0
    for i in range(50):
        res += i
    print(res)
test()
结果:1225

需求:要想计算上述函数的运行时间,既不修改被修饰函数的源代码,又不修改被修饰函数的调用方式,关键还要能添加进附加功能,如何实现?

如下,初级版本一直接修改了被修饰函数的源代码

import time
def test():
    start_time = time.time()
    res = 0
    for i in range(50):
        time.sleep(0.1)
        res += i
    print(res)
    end_time = time.time()
    print(执行的时间 %s %(end_time - start_time))
test()
结果:1225
执行的时间 5.027297258377075

这么做是不可行的,如果有一百个函数呢,需要去改一百个函数的源代码。

 

Python装饰器的知识要点:

装饰器=高阶函数+函数嵌套+闭包

我们从这三个知识点,循序渐进,一点点演变,最后完成上述的需求

先看使用高阶函数的版本二:

import time                  //被修饰函数的源代码没有动
def test():
    res = 0
    for i in range(50):
        res += i
    print(res)

def print_time(func):
    start_time = time.time()
    func()
    time.sleep(1)
    end_time = time.time()
    print(执行的时间 %s %(end_time - start_time))

print_time(test)              //被修饰函数的调用方式被修改了
结果:1225
执行的时间 1.0009217262268066

被修饰函数的源代码确实没有修改,但是被修饰函数的调用方式发生了变化,不合格。

再看使用高阶函数的版本三:

import time
def test():
    res = 0
    for i in range(50):
        res += i
    print(res)

def print_time(func):
    start_time = time.time()
    func()
    time.sleep(1)
    end_time = time.time()
    print(执行的时间 %s %(end_time - start_time))
    return func            //这步是关键,把当参数穿进去的函数,再热return回来,为了后面赋值给原本的函数名test,这样就可以不修改被修饰函数的调用方式

test = print_time(test)    //赋值给原本的函数名test
test()                     //被修饰函数的调用方式没有变化
结果:1225
执行的时间 1.0000982284545898
1225

看似符合要求了,但是我们看运行结果,test()被执行了两遍,还是不合格。

所以光靠高阶函数,无法达到目标,现在来看函数嵌套和闭包

函数嵌套是指在一个函数里定义另一个函数,而不是在一个函数里调用另一个函数

闭包:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。它只不过是个“内层”的函数,由一个名字(变量)来指
代,而这个名字(变量)对于“外层”包含它的函数而言,是本地变量。

 技术分享图片

 

装饰器

标签:内部函数   ack   函数名   str   func   无法   fun   turn   UNC   

原文地址:https://www.cnblogs.com/xulan0922/p/10119127.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!