Python学习笔记: 装饰器Decorator

介绍

装饰器是对功能函数的加强. 在原来的功能函数之外,另外定义一个装饰器函数,对原来的功能函数进行封装(wrapper)并在wrapper的过程中增加一些辅助功能。

应用场景

如下场景:

业务函数func_biz_1(), func_biz_2()... 里面写的是业务逻辑代码。如果我们现在希望在每个函数里面增加一些辅助功能(比如打印日志,计算函数运行时间)

这些辅助功能的代码都是通用的。不使用decorator的情况下我们就要在业务函数里面增加这些辅助代码,缺点:

  • 辅助功能的代码重复copy到每个功能func中
  • 修改辅助功能的代码很麻烦
  • 业务func里面同时有业务逻辑和辅助功能的代码混在一起。代码量变大,且非常乱。

要解决这个问题就要用装饰器,将业务函数封装(wrapper),在wrapper的过程中将辅助功能代码加进去。

代码例子

不用装饰器

一个函数里面既有主业务逻辑(打印质数),又有辅助功能(对函数执行时间计时)

import time

# 判断输入的num是否是质数
def is_prime(num):
  ''' Tell if num is a prime number '''

  if num < 2:
    return False
  if num == 2:
    return True
  for i in range(2, num):
    if num % i == 0:
      return False

  return True

# 打印2到10000之间所有的质数
def prime_numbers():
  ''' print all the prime numbers btw 2...10000
      print the onsumed time
  '''

  t_start = time.time()
  for i in range(2, 10000):
    if is_prime(i):
      print(i)
  t_stop = time.time()

  print("time consumed: {}".format(t_stop - t_start))

prime_numbers()

缺点: 统计时间的代码和业务代码混在一起写在prime_numbers()里面

用装饰器

import time

# 定义一个装饰器: 统计函数运行时间
def display_time(func):
  ''' define a decorator函数,参数是函数 '''

  def wrapper():
      t_start = time.time()
      func()
      t_stop = time.time()
      print("time consumed: {:.4}".format(t_stop - t_start))

  return wrapper

# 判断输入的num是否是质数
def is_prime(num):
  ''' Tell if num is a prime number '''

  if num < 2:
    return False
  if num == 2:
    return True
  for i in range(2, num):
    if num % i == 0:
      return False

  return True

# 打印2到10000之间的质数count
@display_time
def prime_numbers():
  ''' count the prime numbers btw 2...10000 '''

  for i in range(2, 10000):
    if is_prime(i):
      print(i)

prime_numbers() # 运行它的时候实际上运行的是装饰器函数wrapper() 

通过装饰器实现了业务逻辑与主服务功能的分离

posted @ 2022-04-18 10:58  yahoon  阅读(80)  评论(0编辑  收藏  举报