python高级语法学习笔记:装饰器

本文采取循序渐进的方式记录博主学习装饰器,并通过由简到繁的方式分析装饰器的优点和好处,欢迎交流讨论

文章目录

  • 一、引入装饰器1
    • 需求:对f1和f2函数增加打印时间戳
    • 解决办法
    • 结论
  • 二、引入装饰器2
    • 需求不变
    • 装饰器的一般形式
    • 初始使用办法
    • 结论
  • 三、装饰器语法
    • 使用方法
    • 结论
  • 四、装饰器修饰参数不同的函数
    • 方案:
    • 结论
  • 五、装饰包含关键字参数的函数
    • 方案:
    • 总结
  • 六、装饰器总结

一、引入装饰器1

需求:对f1和f2函数增加打印时间戳

import time
def f1():
    print("this is function1!")
def f2():
    print("this is function2!")

解决办法

def print_time(fun):
    print(time.time())
    fun()

# 做法一:
print(time.time())
f1()
print(time.time())
f2()
# 做法二
print_time(f1)
print_time(f2)

结论

  1. 两种简单的做法
  2. 没有建立与原函数的关联
  3. 使用麻烦

二、引入装饰器2

需求不变

import time

def f1():
    print("this is function1!")
def f2():
    print("this is function2!")

装饰器的一般形式

def decorator(fun):
    def wrapper():
        print(time.time())
        fun()
    return wrapper

初始使用办法

decorator_f1 = decorator(f1)
decorator_f1()
decorator_f2 = decorator(f2)
decorator_f2()

结论

  1. 使用嵌套函数
  2. 缺点明显:

仍然没有建立与原函数之间的关联
使用更加麻烦,甚至比上一种还麻烦

三、装饰器语法

使用方法

函数上一行加:@decorator
@[function],function为装饰器名称

import time
def decorator(fun):
    def wrapper():
        print(time.time())
        fun()
    return wrapper

@decorator
def f1():
    print("this is function1!")

@decorator
def f2():
    print("this is function2!")
f1()
f2()

结论

使用装饰器解决了几个非常重要的问题

  1. 符合开闭原则,并没有修改原函数的结构和内容。
  2. 语法简单,快速建立和原函数的关联。
  3. 调用方式保持不变,使用原函数名调用。
  4. APO:面对切向编程

四、装饰器修饰参数不同的函数

方案:

使用*args

import time
def decorator(fun):
    def wrapper(*args):
        print(time.time())
        fun(*args)
    return wrapper

@decorator
def f1(para1):
    print("this is function1!")
    print("parameter" + para1)

@decorator
def f2(para1, para2):
    print("this is function2!")
    print("parameter" + para1 + para2)

f1('1')
f2('1','2')

结论

接收参数的语法:

  1. 单个参数
  2. 多个参数: *args

明显多个参数具有普遍性

五、装饰包含关键字参数的函数

方案:

添加 **kw
注释,kw:kwy word

import time

def decorator(fun):
    def wrapper(*args, **kw):
        print(time.time())
        fun(*args, **kw)
    return wrapper

@decorator
def f1(para1):
    print("this is function1!")
    print("parameter" + para1)

@decorator
def f2(para1, para2):
    print("this is function2!")
    print("parameter" + para1 + para2)

def f3(para1, para2, **kw):
    print("this is function2!")
    print("parameter" + para1 + para2)
    print(kw)

f1('1')
f2('1','2')
f3('1','2',a=1,b=2)

总结

如何解决包含关键字参数的问题?
装饰器完整版:

def decorator(fun):
    def wrapper(*args, **kw):
        print(time.time())
        fun(*args, **kw)
    return wrappe

六、装饰器总结

体现了什么思想,起到了什么作用?

  1. 最基本的思想:(稳定性)
    修改某个被封装的单元,不去改变具体的实现,而是利用装饰器来改变行为!
  2. 提炼共有属性:(复用性)
    比如f1/f2/f3都要打印出时间戳,他们是重复的,就可以使用装饰器来提炼!
  3. 符合开闭原则:
    不破坏代码的封闭性
  4. 大段代码插入:
    装饰器可以包含非常多的代码,这时可以简化代码的内容
  5. 检查用户权限:
    如果想要验证用户的账号密码也可以通过装饰器完成

你可能感兴趣的:(python)