python私房菜--浅谈装饰器

浅谈装饰器

装饰器:本质是函数,(装饰其他函数)就是为其他函数添加附加功能

装饰器原则:

  1. 不能修改被装饰的函数的源代码
  2. 不能修改被装饰的函数的调用方式

实现装饰器知识储备:

  1. 函数即“变量”
  2. 高阶函数
  3. 嵌套函数

例子1:声明普通函数

def func():
    print("我是秃头儿")


# 简单的函数调用
func()
# 打印结果:我是秃头儿

# 打印func函数的内存地址
print(func)  # <function func at 0x000001E2B58D9BF8>
  • 给上面的函数加一个装饰器

例子2:装饰器普通语法

def outer(fn):
    def inner():
        fn()

    # 打印inner函数的内存地址
    print(inner)  # <function outer.<locals>.inner at 0x000002A2BE029E18>
    return inner


@outer
def func():
    print("我是秃头儿")


func()
# 打印func函数的内存地址
print(func)  # <function outer.<locals>.inner at 0x000002A2BE029E18>


  • 声明函数func前面加上 @outer

  • 在调用函数func时,相当于 func = outer(func)

  • 此时的func函数的内存地址发生了变化,变成outer函数的内部inner函数的内存地址

例子3:函数带一个参数装饰器的写法

def outer(fn):
    print("我要买假发~")

    def inner(money):
        print("支付了{}块钱!".format(money))
        fn(money)
        print("购买完成!")
        print("啦啦啦~我头上有头发啦!!!")

    return inner


@outer
def func(money):
    print("我是秃头儿")


func(100)


# 打印结果

# 我要买假发~
# 支付了100块钱!
# 我是秃头儿
# 购买完成!
# 啦啦啦~我头上有头发啦!!!
  • 上面的例子只是一个参数。
  • 倘若要传多个参数,多个参数之中存在整型、字符串、列表、字典等。
  • 这样子写法是不合适的

例子4:函数形参不定参数的写法

def outer(fn):
    print("我要买假发~")

    def inner(*args, **kwargs):
        print("假发的颜色有{}".format(args[1]))
        print("支付了{}块钱!".format(args[0]))
        fn(args)
        print("购买完成!")
        print("啦啦啦~我头上有头发啦!!!")

    return inner


@outer
def func(*args, **kwargs):
    print("我是秃头儿")


color = ["黄色", "蓝色", "绿色"]
func(100, color)

# 打印结果

# 我要买假发~
# 假发的颜色有['黄色', '蓝色', '绿色']
# 支付了100块钱!
# 我是秃头儿
# 购买完成!
# 啦啦啦~我头上有头发啦!!!
  • 上面的代码看上去比"例3"强大了许多
  • 如果在装饰器函数加一个形参
  • 又该怎么办?

例5:在装饰器函数加形参

def decorator(address):
    print("在{}里有卖。".format(address))

    def outer(fn):
        print("我要买假发~")

        def inner(*args, **kwargs):
            print("假发的颜色有{}".format(args[1]))
            print("支付了{}块钱!".format(args[0]))
            fn(args)
            print("购买完成!")
            print("啦啦啦~我头上有头发啦!!!")

        return inner

    return outer


@decorator("理发店")
def func(*args, **kwargs):
    print("我是秃头儿")


color = ["黄色", "蓝色", "绿色"]
func(300, color)

# 打印结果

# 在理发店里有卖。
# 我要买假发~
# 假发的颜色有['黄色', '蓝色', '绿色']
# 支付了300块钱!
# 我是秃头儿
# 购买完成!
# 啦啦啦~我头上有头发啦!!!
  • 要是给装饰器加了一个形参。
  • 就在原来的装饰器外添加一层函数。
  • 最终达到三层函数嵌套。

注:如果一个函数有多个装饰器, 首先执行离它最近的那个装饰器

**例6:**多层装饰器

def supermarket(fn):
    print("---------> 2:start")

    def buy(*args, **kwargs):
        fn()

        print('我戴着假发逛超市')

    print("---------> 2:end")
    return buy


def outer(fn):
    print("---------> 1:start")

    def inner(*args, **kwargs):
        print("我要买假发~")
        fn()
        print("购买完成!")

    print("---------> 1:end")
    return inner


@supermarket
@outer
def func(*args, **kwargs):
    print("我是秃头儿")


func()


# 打印结果
# ---------> 1:start
# ---------> 1:end
# ---------> 2:start
# ---------> 2:end
# 我要买假发~
# 我是秃头儿
# 购买完成!
# 我戴着假发逛超市

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值