• 技术文章 >后端开发 >Python教程

    Python中装饰器是什么?Python中装饰器的介绍

    不言不言2018-09-13 16:50:24原创682
    本篇文章给大家带来的内容是关于Python中装饰器是什么?Python中装饰器的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

    一、什么是装饰器

    装饰器,decorator,本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

    装饰器通过不修改核心代码而增强核心代码部分的功能。例如在函数前插入日志、权限校验、事务处理等场景。
    而且可以抽离出大量与函数功能无关的雷同代码并重用。

    二、早期实现:不是装饰器的装饰器

    例如:

    def foo():
       print("2017-06-08")
    f = foo    # 将函数赋值给变量,f为函数对象
    f()
    # 返回结果:
    2017-06-08

    三、语法糖@ 实现简单装饰器

    假设现在要增强foo()的功能,例如,在函数调用前打印日志。但是又不希望修改foo()函数的定义。在这种代码运行期间动态增加功能的方式,称之为“装饰器”。
    如下:

    def testfunc(func):
        print('testfunc')
        def wrapper():
            print("%s %s() called" %(time.ctime(),func.__name__))
            return func()
        return wrapper
    @testfunc 
    def foo():
        print('foo1()')
    
    foo()  # 相当于执行testfunc(foo) ->wrapper(foo) -> foo()

    执行结果:

    testfunc
    Wed Sep 12 15:01:13 2018 foo() called
    foo1()

    说明:执行foo()前,先执行testfunc(foo),再执行wrapper(),返回时调用foo()本身。

    四、接收特定类型参数的装饰器

    如下:

    def testfunc_with_args(func):
        def wrapper_argus(arg1, arg2):
            print("I got args! Look:", arg1, arg2)
            func(arg1, arg2)
        return wrapper_argus
    @testfunc_with_args
    def full_name(first_name, last_name):  # 带参数,将参数传给被装饰的函数
        print("My name is", first_name, last_name)
    
    full_name("Peter", "Venkman")  # 调用

    执行结果:

    I got args! Look: Peter Venkman
    My name is Peter Venkman

    五、带不定参数的装饰器

    当有多个函数需要调用装饰器,但是函数的参数各不同时,该如何实现呢?总不能一个函数对应一个装饰器吧。这时候就可以用带不定参数的装饰器进行实现。
    如下:

    def log(func):
        def wrapper(*args,**kwargs):        # 可接受各种参数
            print('call %s():'% func.__name__)
            return func(*args,**kwargs)     # 返回一个函数
        return wrapper                      # 装饰器返回一个函数,进入到wrapper()
    
    @log      # @log放到now()的定义处,相当于执行语句:now = log(now)
    def now_1(a,b):
        print('now()1:a+b = ',a+b)
    @log
    def now_2(a,b,c):
        print('now_2():a+b+c = ',a+b+c)
    
    now_1(1,2)
    now_2(1,2,3)

    运行一下哦~

    六、多个装饰器

    当一个函数想要加入多项功能时,可以考虑使用多层装饰器,就是要注意一下装饰器的执行顺序。
    举个栗子:

    # 注意代码的执行顺序
    def deco_1(func):
        print('------111111------')
        def wrapper(*args,**kwargs):    # 包裹函数,参数与原函数的参数一致
            print('start: this is deco_1.')
            func(*args,**kwargs)
            print('end: deco_1.')
        return wrapper  # 返回值是一个包裹函数
    def deco_2(func):
        print('------222222------')
        def wrapper(*args,**kwargs):
            print('start: this is deco_2.')
            func(*args,**kwargs)
            print('end: deco_2.')
        return wrapper
    
    @deco_1
    @deco_2
    def now_1(a,b):
        print('now()1:a+b = ',a+b)
    
    now_1(1,2)

    运行结果:

    # 结果,注意执行顺序:
    ------222222------
    ------111111------
    start: this is deco_1.
    start: this is deco_2.
    now()1:a+b =  3
    end: deco_2.
    end: deco_1.

    七、装饰器本身带参数

    除了给被装饰的函数带参数,装饰器本身也可以带参数。

    def logging(level):
        def wrapper(func):
            def inner_wrapper(*args, **kwargs):
                print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
                return func(*args, **kwargs)
            return inner_wrapper
        return wrapper
        
    @logging(level='INFO')
    def say(something):
        print("say {}!".format(something))
    
    @logging(level='DEBUG')
    def do(something):
        print("do {}...".format(something))
    
    say('hello')
    do("my work")

    执行结果:

    # 执行结果:
    [INFO]: enter function say()
    say hello!
    [DEBUG]: enter function do()
    do my work...

    相关推荐:

    python中的装饰器详解

    Python中的各种装饰器详解

    以上就是Python中装饰器是什么?Python中装饰器的介绍的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:python decorator
    上一篇:python3中setdefault的用法介绍(代码) 下一篇:python如何读写json数据(代码)
    PHP编程就业班

    相关文章推荐

    • 简单上手Python中装饰器的使用• python利用装饰器进行运算的实例分析• Python中使用装饰器和元编程实现结构体类实例• Python装饰器的函数式编程详解• python通过装饰器检查函数参数数据类型的方法

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网