首页 > 编程语言 > 详细

[Python3] 037 函数式编程 装饰器

时间:2019-12-21 21:18:10      阅读:97      评论:0      收藏:0      [点我收藏+]

函数式编程 之

装饰器 Decrator

1. 引子

>>> def func():
...   print("abc")
...
>>> func()
abc
>>> f = func
>>> f()
abc
>>> id(func) - id(f)
0
>>> f.__name__
'func'
>>> 
  • 现在由新的需求
    • func 进行扩展:每次打印 abc 之前打印当前系统时间
    • 但实现这个功能不能改动现有代码
    • => 使用装饰器

2. 简介

  • 在不改动函数代码的基础上无限制扩展函数功能的一种机制
  • 本质上讲,装饰器是一个返回函数高阶函数
  • 装饰器的使用
    • 使用 @ 语法
    • 即,在每次要扩展的函数定义前使用 @ + 函数名

3. 使用

  • 必要的导入
>>> import time
  • 先写好函数备用
>>> def print_date(f):
...   def wrapper(*args, **kwargs):
...     t = time.strftime("%Y-%m-%d", time.localtime())
...     print(f"Date: {t}")
...     return f(*args, **kwargs)
...   return wrapper
...
>>> 

3.1 例子1

  • 对函数进行功能扩展,每次执行函数前,打印当前日期
>>> @print_date
... def func():
...   print("abc")
...
>>> func()
Date: 2019-12-20
abc
>>> 
  • 装饰器的好处
    • 一处定义,多处装饰
    • 一旦被装饰,就能拥有装饰器的功能

3.2 例子2

  • 不使用 @,手动执行装饰器
>>> def manual():
...   print("manual operation")
...
>>> func1 = print_date(manual)
>>> func1()
Date: 2019-12-20
manual operation
>>> 

3.4 例子3

  • 不一定要像 print_date 中的 def wrapper(*args, **kwargs) 那么标准
>>> def cal_time(f):
...   def wrapper(x, y):
...     start = time.perf_counter_ns()
...     f(x, y)
...     stop = time.perf_counter_ns()
...     print(f"run time: {stop - start}")
...   return wrapper
...
>>> @cal_time
... def add_two_nums(x, y):
...   print(f"{x} + {y} = {x + y}")
...
>>> add_two_nums(10, 20)
10 + 20 = 30
run time: 1606600
>>>
  • 注意:装饰器要写在被装饰的函数的上方

3.5 例子4

  • 两个装饰器
>>> def deco1(f):
...   print("decorator1")
...   def wrapper():
...     print("decorator1's wrapper")
...     f()
...   return wrapper
...
>>> def deco2(f):
...   print("decorator2")
...   def wrapper():
...     print("decorator2's wrapper")
...     f()
...   return wrapper
...
>>> @deco2
... @deco1
... def dbl_decos():
...     print("double decorators")
...
decorator1
decorator2
>>> dbl_decos()
decorator2's wrapper
decorator1's wrapper
double decorators
>>>

3.6 例子5

  • 沿用例子4的思路,但是我换种写法,并把这些代码写到一个 .py 的文件中
def deco1(f):
    print("先穿衬衫")
    def wrapper():
        print("再脱衬衫")
        f()
    return wrapper


def deco2(f):
    print("再穿西装")
    def wrapper():
        print("先脱西装")
        f()
    return wrapper


@deco2
@deco1
def dbl_decos():
    print("over")


if __name__ == "__main__":
    dbl_decos()

>>>

先穿衬衫
再穿西装
先脱西装
再脱衬衫
over
  • 装饰的过程:先执行 deco1,再执行 deco2
  • 调用的过程:先调用 deco2,再调用 deco1

[Python3] 037 函数式编程 装饰器

原文:https://www.cnblogs.com/yorkyu/p/12078084.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!