装饰器

简介: python

As we know,装饰器的作用是在不改变原函数逻辑和调用方式的情况下为函数附加新的功能。

def hello():
    print('hello world!')
    return 1

一个非常简单的函数,现在在输出hello world!之前输出星号,在输出hello world!之后输出等号,装饰器如下

def deco():
    def inner(func):
        print('*'*12)
        func()
        print('='*12)
    return inner

原函数使用装饰器

@deco
def hello():
    print('hello world!')
    return 1

调用函数即可看到如下输出
image.png
使用@符号相当于执行了以下两步

hello = deco(hello)
hello()

函数也是一个对象,可以当作参数传递给其它函数,第一步把hello当作参数传递给deco函数,deco返回inner函数,然后在把inner函数赋值给hello,这样的话再次调用hello的时候其实执行的是inner的逻辑,由于把原hello函数当作参数传递给了inner,所以在inner内调用原函数即可。
但是,这样的装饰器是有问题的

原函数返回值

原函数是有返回值的,但是经过装饰器调用之后把inner赋值给了原函数,然而inner无返回值,这就尴尬了,所以要让inner返回原函数的返回值

def deco(func):
    def inner():
        print('*' * 12)
        ret = func()  # 接收原函数返回值
        print('=' * 12)
        return ret
    return inner

返回值问题解决了,但是,函数名却变了

函数名问题

没使用装饰器的时候

print(hello.__name__)  # 输出hello

使用装饰器后

@deco
def hello():
    pass
print(hello.__name__)  # 输出inner

函数名变了,好像也不太对~
解决这个问题,使用内置模块functools改造装饰器

def deco(func):
    @functools.wraps(func)
    def inner():
        ret = func()
        return ret
    return inner

这样的装饰器只能用于没有参数的函数,对于有参数的函数怎么搞?

函数参数

def deco(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret
    return inner

因为给函数使用装饰器后,原函数其实就变成了装饰器的内部函数,那么原函数的参数就是传递给装饰器的内部函数,装饰器的内部函数就要能够接收参数

给装饰器指定参数

def deco_params(*arg, **kw):
    def deco(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            ret = func(*args, **kwargs)
            return ret
        return inner
    return deco

使用装饰器

@deco_params(1, 2)
def hello(a, b):
    pass

调用过程

deco = deco_params(1, 2)
hello = deco(hello)
hello(3, 4)
目录
相关文章
|
29天前
|
JavaScript
03_装饰器
03_装饰器
45 1
|
29天前
22_自定义装饰器
22_自定义装饰器
69 0
|
11月前
|
Python
一日一技:装饰器如何装饰异步函数
一日一技:装饰器如何装饰异步函数
110 0
|
7月前
|
安全
闭包和装饰器
闭包和装饰器
|
存储 JavaScript 前端开发
装饰器语法
利用typeof判定类型的取值范围是:'undefined' /'boolean' /'string' /'number' /'object' /'function' /'symbol' 在JavaScript内部使用typeof判断类型依据的是二进制,根据变量的机器码低位1-3位存储其类型信息,有如下规则:
78 0
|
存储 缓存 关系型数据库
Python装饰器1-闭包与函数装饰器
闭包与函数装饰器:被装饰函数不带参数、被装饰函数带参数、装饰器带参数,装饰器的调用
Python装饰器1-闭包与函数装饰器
|
开发者 Python
装饰器详解|学习笔记
快速学习装饰器详解
76 0
|
Python
Python编程:decorator装饰器
Python编程:decorator装饰器
|
JSON 数据格式
装饰器的实际应用
使用装饰器模式改造slf4j打印json格式日志
696 0
装饰器的实际应用