首页 > 编程语言 > 详细

Python3学习笔记(十三):装饰器

时间:2018-06-03 21:03:13      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:nbsp   lee   一个   col   false   UNC   for   strong   直接   

装饰器就是一个闭包,它的主要作用是在不改变原函数的基础上对原函数功能进行扩展。

我们先来写一个简单的函数:

from time import sleep


def foo():
    print("Hello World!")
    sleep(2)

现在我们要对这个函数加一些功能,比如说打印这个函数的执行时间

有人说,这还不简单啊,直接修改foo函数呢,确实,这是最简单的一种方法。但是在我们实际工作中,有时候是不能对调用的函数进行修改的,那该怎么办呢?

我们可以重新写个打印时间的函数去调用foo函数啊,比如:

import time
from time import sleep

def foo():
    print("Hello World!")
    sleep(2)

def show_time(func):
    start_time = time.time()
    func()
    end_time = time.time()
    print(end_time - start_time)

调用:

show_time(foo)

# 输出:
Hello World!
2.0000178813934326

很好,确实是在不修改foo函数的基础上实现了需求,但是。。。。。有个大问题,改变了函数的调用方式,前面是调用foo()的,现在需要修改成调用show_time()。

看来这种方法也不行。

这个时候就是闭包大展身手的机会了

import time
from time import sleep

def foo():
    print("Hello World!")
    sleep(2)

def show_time(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time - start_time)
    return inner

#  调用
foo = show_time(foo)
foo()

# 输出
Hello World!
2.000027656555176

到这里已经完美地实现了我们的需求,这就是装饰器。装饰器有个高大上的写法,就是装饰器符号@

上面的代码我们修改成用装饰器符号@来写:

import time
from time import sleep

def show_time(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time - start_time)
    return inner

@show_time    # 其实就相当于foo = show_time(foo)
def foo():
    print("Hello World!")
    sleep(2)

# 调用
foo()

@show_time的作用就是执行foo()时,跳转到去执行inner(),如下图:

技术分享图片

被装饰函数的参数

如果被装饰的函数有形参,那么在装饰器函数中该怎么写呢?

import time
from time import sleep


def show_time(func):
    def inner(*x):
        start_time = time.time()
        func(*x)
        end_time = time.time()
        print(end_time - start_time)
    return inner


@show_time
def add(*args):
    sum = 0
    for arg in args:
        sum += arg
    print(sum)
    sleep(2)


add(3, 5)

装饰器函数参数

有些时候我们可能需要对不同的被装饰函数加些不同的功能,比如需要对某些函数加上日志打印,那该怎么做呢?

import time
from time import sleep


def logger(flag="false"):
    def show_time(func):
        def inner(*x):
            start_time = time.time()
            func(*x)
            end_time = time.time()
            print(end_time - start_time)
            if flag == "true":
                print("打印日志记录")
        return inner
    return show_time


@logger("true")   # 打印日志记录
def add(*args):
    sum = 0
    for arg in args:
        sum += arg
    print(sum)
    sleep(2)

@logger()   # 不需要打印日志记录
def foo():
    print("Hello World!")
    sleep(2)

 

Python3学习笔记(十三):装饰器

标签:nbsp   lee   一个   col   false   UNC   for   strong   直接   

原文:https://www.cnblogs.com/eastonliu/p/9130021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号