python之装饰器

本文深入探讨了Python装饰器的使用,从基本概念出发,逐步介绍了装饰器如何帮助我们遵守开放封闭原则,即对修改封闭,对扩展开放。通过具体实例,如计算函数执行时间,展示了装饰器的强大功能和灵活性。
import time
def foo():
    print('foo......')
    time.sleep(1)

foo()

想上面的函数运行用了多长时间,可通过下面的方式实现。(上面的time.sleep(1)是防止程序运行时间太短,打印时间时显示为0)

import time

def foo():
    start = time.time()
    print("foo......")
    time.sleep(1)
    end = time.time()
    print("spend %s" %s (end-start))

foo()

为了遵守开放封闭原则,我们将上述实现进行修改(尤其当需要计算时间的函数非常多时)。

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


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

show_time(bar)

 上述实现方式的缺点时改变了函数调用方式,原来时调用bar(),现在时调用show_time(bar)。

import time


# 遵守开放封闭原则,对修改封闭,对扩展开放
def foo():
    print('foo……')
    time.sleep(2)


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


foo = show_time(foo)

上述代码中的inner是一个闭包函数。 当其他函数也需要计算时间时,假设该函数是bar(),只需要调用bar = show_time(bar)即可。

python提供了一种较为简单的写法:

import time


# 遵守开放封闭原则,对修改封闭,对扩展开放
def show_time(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print('spend %s' % (end - start))
    return inner

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

将foo()函数放在show_time()函数下面,在foo()函数前加上@show_time,就可实现上述功能,@show_time的功能就相当于下面注释掉的foo = show_time(foo)。其中show_time函数就是装饰器函数。

被装饰函数有参数时,参数是传给了闭包函数,也就是上述代码中的inner函数。

import time


# 遵守开放封闭原则,对修改封闭,对扩展开放
def show_time(f):
    def inner(x, y):
        start = time.time()
        f(x, y)
        end = time.time()
        print('spend %s' % (end - start))
    return inner

@show_time
def add(a, b):
    print(a+b)
    time.sleep(2)

add(1, 2)

 如果add()中的参数个数是不确定的,采用*a,**b的方式传递(下面代码的**b实际上没有接受到参数,参数全都传到了a中)

import time


# 遵守开放封闭原则,对修改封闭,对扩展开放
def show_time(f):
    def inner(*x, **y):
        start = time.time()
        f(*x, **y)
        end = time.time()
        print('spend %s' % (end - start))
    return inner

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


add(1, 2, 5, 7)

 装饰器也可以加参数,嵌套的logger()的作用就是为了接收flag参数值。

import time


# 遵守开放封闭原则,对修改封闭,对扩展开放
# 装饰器函数加参数
def logger(flag):

    def show_time(f):
        def inner(*x, **y):
            start = time.time()
            f(*x, **y)
            end = time.time()
            print('spend %s' % (end - start))
            if flag == 'true':
                print('日志记录  ')
        return inner

    return show_time


@logger(flag='true')  # 返回show_time,相当于@show_time
def add(*a, **b):
    sums = 0
    for i in a:
        sums += i
    print(sums)
    time.sleep(2)


add(1, 2, 5, 7)



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值