python3核心编程——装饰器

定义两个功能函数:

# -*- coding:utf-8 -*-


def foo():  # 打印"foo..."
    print("foo...")
    

def bar():  # 打印"bar..."
    print("bar...")
    
    
foo()  # foo...
bar()  # bar...
View Code

计算函数的运行时间,我们可以把函数改写为:

import time  # 放在(文档)最顶端


def foo():
    start = time.time()  # 函数运行之前的时刻
    
    print("foo...")
    time.sleep(1)  # 因为该程序运行时间太短,所以运用time.sleep()延长1s时间
    
    end = time.time()  # 函数运行完后的时刻
    print(end - start)  # 打印运行的时间
    
    
def bar():
    start = time.time()  # 函数运行之前的时刻
    
    print("bar...")
    time.sleep(1)  # 因为该程序运行时间太短,所以运用time.sleep()延长1s时间
    
    end = time.time()  # 函数运行完后的时刻
    print(end - start)  # 打印运行的时间
    
    
foo()
# foo...
# 1.0006506443023682

bar()
# bar...
# 1.0007519721984863
View Code

通过在每个功能函数内部添加一些计算时间的代码,就能实现我们的需求,但是又出现了以下问题:

  1、修改了功能函数本身(每次调用函数,都会打印运行的时间,如果有的时候,我不想打印呢?)。

  2、代码量大,且重复(此处只有2个功能函数,我们可手动修改,如果有几十个,几百个,那岂不是要改到天手抽筋)。

 

所以,针对以上两点情况,及解决代码重复不修改函数本身,我们可以新定义一个计算时间的函数:

import time


def foo():   # 打印"foo..."
    print("foo...")
    

def bar():  # 打印"bar..."
    print("bar...")
    
    
def caltime(func):  # 计算函数运行的时间
    start = time.time()  # 函数运行之前的时刻
    
    func()
    time.sleep(1)  # 因为该程序运行时间太短,所以运用time.sleep()延长1s时间
    
    end = time.time()  # 函数运行完后的时刻
    print(end - start)
    
    
caltime(foo)
# foo...
# 1.0009233951568604

caltime(bar)
# bar...
# 1.0008749961853027
View Code

我们发现,通过新建一个函数来实现一个功能,很方便、简洁。但是这样,函数的调用方式却发生了改变,比如:

我们最开始调用功能函数是:foo() 。现在要计算函数运行时间,我们的调用方式是:caltime(foo)

我们需要达到的需求是:就最终执行foo(),就可实现该函数本身的功能计算该函数运行的时间。而不是caltime(foo)。

 

如果我们的项目中调用了几十次foo函数,并且都需要计算时间,那我们岂不是也要挨个把foo()改成caltime(foo) ,其实这也是一件恼火的事情。所以我们得像个办法(就是还是书写foo()调用函数,但是同时可以计算运行的时间):

import time


def foo():   # 打印"foo..."
    print("foo...")
    

def bar():  # 打印"bar..."
    print("bar...")


def caltime(func):
    def inner():
        start = time.time()
    
        func()
        time.sleep(1)
    
        end = time.time()
        print(end - start)
    
    return inner


foo = caltime(foo)
foo()
# foo...
# 1.0006935596466064
View Code

最后我们就是通过foo()而不是caltime(foo)来调用函数的。所以,我们就可通过把函数当作返回值传递,来实现最终的调用方式(调用函数时的书写方式)相同。

caltime(foo)的执行结果是,返回的inner函数(并不会执行inner函数),然后把这个inner函数赋值给foo(即foo=caltime(foo))。所以,foo()就相当于在执行inner()。

这里的caltime()就是装饰器,但是我们会发现,每次执行foo()之前,都会写上foo=caltime(foo),也挺麻烦的,所以装饰器更专业更优雅写法就是:

  1、把装饰器caltime()写在功能函数前面;

  2、把foo=caltime(foo)这句每次调用都会写(重复)的代码写成 @caltime 的方式,放到功能函数前面。

import time


def caltime(func):
    def inner():
        start = time.time()
    
        func()
        time.sleep(1)
    
        end = time.time()
        print(end - start)
    
    return inner


@caltime  # 此时caltime就相当于是foo=caltime(foo)
def foo():   # 打印"foo..."
    print("foo...")
    

def bar():  # 打印"bar..."
    print("bar...")


# foo = caltime(foo)
foo()
# foo...
# 1.000216007232666
View Code

 

转载于:https://www.cnblogs.com/tom-blogs/p/11202559.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值