Python学海无涯路【第21回】:装饰器


1、什么是装饰器

装饰器可为函数增加新的功能,并且不改变原函数的:

  • 内部结构
  • 返回值
  • 调用方式

2、函数可赋值给变量

例一:

def hello():
    print("你好")
hi=hello
hi()

输出:
你好

例二:

def hello():
    print("你好")
hi=hello
del hello #删除hello
hello()

NameError: name ‘hi’ is not defined

例三:

def hello():
    print("你好")
hi=hello
del hello #删除hello
hi()

输出:
你好

3、函数嵌套

例一:

def say():
    def hi():
        print("你好")
    def bye():
        print("再见")
    hi()
    bye()
say()

输出:
你好
再见

例二:

def say():
    def hi():
        print("你好")       
hi()						#出了hi()的作用域

NameError: name ‘hi’ is not defined

4、从函数中返回函数

例一:

def say():
    def hi():
        print("你好")
    return hi
a=say()			#a将指向,say函数中的hi函数
print(a)
print(a())

输出:
<function say..hi at 0x000000DF56C729D8>
你好
None

5、函数做为参数传递给另一个函数

例一:

def hi():
    return "你好"
def say(func):
    print("说")
    print(func())
say(hi)

输出:

你好

6、第一个装饰器

例一:

def say(func):
    def wrapper():
        print("调用fcunc前")
        func()
        print("调用fcunc后")
    return wrapper

def hi():
    print("你好")
    
hi()

输出:
你好
例二:
这差不多就算是一个装饰器了

def say(func):
    def wrapper():
        print("调用fcunc前")
        func()
        print("调用fcunc后")
    return wrapper

def hi():
    print("你好")

hi=say(hi)  #调用装饰器
hi()

输出:
调用fcunc前
你好
调用fcunc后

例三:
用 @ 来运行例二的程序

def say(func):
    def wrapper():
        print("调用fcunc前")
        func()
        print("调用fcunc后")
    return wrapper
@say
def hi():
    print("你好")
    
hi()

输出:
调用fcunc前
你好
调用fcunc后

例四:

def say(func):
    def wrapper():
        print("调用fcunc前")
        ret=func()
        print("调用fcunc后")
        return "返回wrapper"
    return wrapper
@say
def hi():
    print("你好")
    return "返回hi"

ret=hi()
print(ret)

输出:
调用fcunc前
你好
调用fcunc后
返回wrapper

hi实际返回的是wrapper的返回值,下面我们让装饰器返回hi的返回值
例五:

def say(func):
    def wrapper():
        print("调用fcunc前")
        ret=func()
        print("调用fcunc后")
        return ret
    return wrapper
@say
def hi():
    print("你好")
    return "返回hi"

ret=hi()
print(ret)

输出:
调用fcunc前
你好
调用fcunc后
返回hi

这样就实现了,调用了hi后返回值也是hi的

7、适应原函数带参数的装饰器

7.1、原函数带一个参数

例一:

def say(func):
    def wrapper(name):
        print("调用fcunc前")
        ret=func(name)
        print("调用fcunc后")
        return ret
    return wrapper
@say
def hi(name):
    print("你好%s"%name)
    return "返回hi"

hi("锄禾")

输出:
调用fcunc前
你好锄禾
调用fcunc后

装饰器的缺点是,原函数形参数量变化以后,装饰器也需要对应维护

7.1、原函数不定长参数

下面这种形式的装饰器可以适应任意数量形参的原函数
例一:

def say(func):
    def wrapper(*args,**kwargs):
        print("调用fcunc前")
        ret=func(*args,**kwargs)
        print("调用fcunc后")
        return ret
    return wrapper
@say
def hi(name,age):
    print("你好%s,我今年%s"%(name,age))
    return "返回hi"

ret=hi("锄禾",18)
print(ret)

输出:
调用fcunc前
你好锄禾,我今年18
调用fcunc后

8、*args和**kwargs

详见
Python学海无涯路【第08回】:函数
2.4、不定长参数

9、为装饰器传参

例一:

def say_type(type=1):
    def say(func):
        def wrapper(*args,**kwargs):
            if (1==type):
                print("功能一")
            else:
                print("功能二")
            ret=func(*args,**kwargs)
            return ret
        return wrapper
    return say
@say_type(2)			#为装饰器传参
def hi(name):
    print("你好%s"%(name))
    return "返回hi"

输出:
功能二
你好锄禾

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值