python 装饰器@

装饰器@

     装饰器就是用一个函数A去修饰一个函数B,可以使得A,B代码分离,逻辑上更清晰。比如我们要计算判断素数所使用的的时间,一般会写成如下代码:

import time


def is_prime(n):
    if n == 2:
        return True
    else:
        for i in range(2, n):
            if n % i == 0:
                return False
        return True


def prime():
    t1 = time.time()
    for i in range(2, 1000):
        if is_prime(i):
            print(i)
        else:
            pass
    t2 = time.time()
    print(t2 - t1)
prime()

     用装饰器可以将计算时间的代码抽离出来,如下:

import time

def calculate_time(func):
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        print(t2 - t1)
    return wrapper


def is_prime(n):
    if n == 2:
        return True
    else:
        for i in range(2, n):
            if n % i == 0:
                return False
        return True

@calculate_time
def prime():
    for i in range(2, 1000):
        if is_prime(i):
            print(i)
        else:
            pass


prime()

      两者在效果上是一样的,而且计算时间的装饰器可以多次使用在不同函数上。

带参数的函数装饰器
      函数需要传入参数,只需要在wrapper()传入*args即可。以判断素数为例,假设我们需要判断2-10000之间的素数,代码如下:

import time

def calculate_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        func(*args, **kwargs)
        t2 = time.time()
        print(t2 - t1)
    return wrapper


def is_prime(n):
    if n == 2:
        return True
    else:
        for i in range(2, n):
            if n % i == 0:
                return False
        return True

@calculate_time
def prime(num):
    for i in range(2, num):
        if is_prime(i):
            print(i)
        else:
            pass


prime(10000)

带返回值的函数装饰器
      假设我们现在需要统计1000以内的素数数量,可以如下书写代码:

import time

def calculate_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        count = func(*args, **kwargs)
        t2 = time.time()
        print(t2 - t1)
        return count
    return wrapper


def is_prime(n):
    if n == 2:
        return True
    else:
        for i in range(2, n):
            if n % i == 0:
                return False
        return True

@calculate_time
def prime(num):
    count = 0
    for i in range(2, num):
        if is_prime(i):
            print(i)
            count += 1
        else:
            pass
    return count


total_count = prime(1000)
print("1000以内的素数数量为:", total_count)

多个装饰器嵌套
假设有三个装饰器,代码如下:

'''
    多个装饰器装饰一个函数
    定义阶段:自下而上加载;
    执行阶段:自上而下运行;
'''


# 定义第一个装饰器
def set_func1(func):
    print("set_func1")

    def wrapper1(*args, **kwargs):
        print('装饰内容开始1')
        func(*args, **kwargs)
        print('装饰内容结束1')
    return wrapper1


# 定义第二个装饰器
def set_func2(func):
    print("set_func2")

    def wrapper2(*args,**kwargs):
        print('装饰内容开始2')
        func(*args, **kwargs)
        print('装饰内容结束2')
    return wrapper2


# 定义第二个装饰器
def set_func3(func):
    print("set_func3")

    def wrapper3(*args, **kwargs):
        print('装饰内容开始3')
        func(*args, **kwargs)
        print('装饰内容结束3')
    return wrapper3


@set_func1
@set_func2
@set_func3
def show():
    print('Show Run....')


# show()


# 结果如下:
# 装饰内容开始1
# 装饰内容开始2
# 装饰内容开始3
# Show Run....
# 装饰内容结束3
# 装饰内容结束2
# 装饰内容结束1
#
# 进程已结束,退出代码 0

      多个装饰器修饰一个函数时,定义(加载阶段)自下而上,注释show()运行的结果如下:

set_func3
set_func2
set_func1

执行代码阶段是自上而下运行的,运行show()得到的结果如下:
set_func3
set_func2
set_func1
装饰内容开始1
装饰内容开始2
装饰内容开始3
Show Run…
装饰内容结束3
装饰内容结束2
装饰内容结束1

运行阶段包括了加载,此时
show=set_func1(set_func2(set_func3(show())))

即先运行装饰器set_func1,执行到show函数时,执行
set_func2(set_func3(show()))

也就是开始执行装饰器set_func2,如此下去,相当于递归。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值