一、装饰器的特征

  • 能把被装饰函数替换成其他函数
  • 装饰器在加载模块时立即执行

    二、装饰器函数在导入时执行

    以下代码中,第5行 print(f"running register({func})")在被装饰函数定义后立即执行 ```python registry = []

def register(func): print(f”running register({func})”) registry.append(func) return func

@register def f1(): print(“running f1()”)

@register def f2(): print(“running f2()”)

def f3(): print(“running f3()”)

if name == “main“: print(“running main()”) print(“registry ->”, registry) f1() f2() f3()

  1. # running register(<function f1 at 0x000001D749157F28>)
  2. # running register(<function f2 at 0x000001D74915B400>)
  3. # running main()
  4. # registry -> [<function f1 at 0x000001D749157F28>, <function f2 at 0x000001D74915B400>]
  5. # running f1()
  6. # running f2()
  7. # running f3()
  1. <a name="WPUhY"></a>
  2. ## 三、使用装饰器改进“策略”模式
  3. 如前述电商打折实例,为了避免新增策略函数后忘记将其加入promos列表中,导致best_promo忽略新策略而且不报错,引入不易察觉的缺陷。使用注册装饰器则可解决这个问题。
  4. ```python
  5. promos = []
  6. def promotion(promo_func):
  7. promos.append(promo_func)
  8. return promo_func
  9. @promotion
  10. def fildlity(order):
  11. pass
  12. @promotion
  13. def bulk_item(order):
  14. pass
  15. @promotion
  16. def large_order(order):
  17. pass
  18. def best_promo(order):
  19. return max(promo(order) for promo in promos)