Miao Love

python装饰器

装饰器

  • 增强某一函数的功能,但是又不希望修改原函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。代码需要遵循开放封闭原则,已经实现的功能代码不允许被修改,但可以扩展。

  • 比如先写一个判断质数的函数(该数除了1和它本身以外不再有其他的因数)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def is_prime(num):
    if num < 2:
    return False
    elif num == 2:
    return True
    else:
    for i in range(2,num):
    if num % i == 0:
    return False
    return True
  • 定义一个函数,输出区间范围的质数

    1
    2
    3
    4
    5
    def prime_nums():
    for i in range(2,100):
    if is_prime(i):
    print(i,end=",")
    prime_nums()
  • 输出结果为

    1
    2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
  • 我们想计算一下找出质数用了多长时间,我们可以这样(尽量参数大一些)

    1
    2
    3
    4
    5
    6
    7
    8
    def prime_nums():
    t1 = time.time()
    for i in range(2,10000):
    if is_prime(i):
    print(i)
    t2 = time.time()
    print(t2 - t1)
    prime_nums()
  • 输出结果为

    1
    2
    3
    4
    5
    6
    ...
    9941
    9949
    9967
    9973
    0.28626275062561035
  • 那么我想要用装饰器去算出时间,首先先写装饰器,并加到函数上面运行结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #装饰器的书写
    def date_time(func):
    def wrapper(*args):
    t1 = time.time()
    func(*args)
    t2 = time.time()
    print(t2 - t1)
    return wrapper

    #将装饰器添加到应用函数当中
    @date_time
    def prime_nums(nums):
    for i in range(2, nums):
    if is_prime(i):
    print(i)

    prime_nums(10000)
  • 执行结果

    1
    2
    3
    4
    5
    6
    ...
    9941
    9949
    9967
    9973
    0.2872016429901123
  • 从上述函数所得到装饰器的作用非常的方便,那么如果应用函数return一个值的时候,这样的装饰器需要再做小小的改动,将返回值传到装饰器中,才可使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #装饰器
    def date_time(func):
    def wrapper(*args):
    t1 = time.time()
    result = func(*args)
    t2 = time.time()
    print(t2 - t1)
    return result
    return wrapper

    #返回质数的个数和
    @date_time
    def prime_nums(nums):
    count = 0
    for i in range(2, nums):
    if is_prime(i):
    count = count + 1
    return count

    count = prime_nums(10000)
    print(count)
  • 执行结果

    1
    2
    0.28022122383117676
    1229
  • 这样子我们就能看到装饰器当中也要传值,并且返回函数的值,才能在最后的结果中显示。

  • 更好的展示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    def date_time(func):
    def wrapper(*args):
    t1 = time.time()
    result = func(*args)
    t2 = time.time()
    print("time: {:.4} s".format(t2 - t1))
    return result
    return wrapper

    @date_time
    def prime_nums(nums):
    count = 0
    for i in range(2, nums):
    if is_prime(i):
    count = count + 1
    return count

    count = prime_nums(10000)
    print("质数的个数:%s"%count)
  • 执行结果

    1
    2
    time: 0.2793 s
    质数的个数:1229
打赏