zoukankan      html  css  js  c++  java
  • 【Python】解析Python中的装饰器

    python中的函数也是对象,函数可以被当作变量传递。

    装饰器在python中功能非常强大,装饰器允许对原有函数行为进行扩展,而不用硬编码的方式,它提供了一种面向切面的访问方式。

    装饰器

    一个普通的装饰器一般是这样:

    import functools
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print('call %s():' % func.__name__)
            print('args = {}'.format(*args))
            return func(*args, **kwargs)
        return wrapper

    这样就定义了一个打印出方法名及其参数的装饰器。
    调用之:

    @log
    def test(p):
        print(test.__name__ + " param: " + p)
    
    test("I'm a param")

    输出:

    call test():
    args = I'm a param
    test param: I'm a param

    装饰器在使用时,用了@语法,让人有些困扰。其实,装饰器只是个方法,与下面的调用方式没有区别:

    def test(p):
        print(test.__name__ + " param: " + p)
    
    wrapper = log(test)
    wrapper("I'm a param")

    @语法只是将函数传入装饰器函数,并无神奇之处。
    值得注意的是@functools.wraps(func),这是python提供的装饰器。它能把原函数的元信息拷贝到装饰器里面的 func 函数中。函数的元信息包括docstring、name、参数列表等等。可以尝试去除@functools.wraps(func),你会发现test.__name__的输出变成了wrapper。

    带参数的装饰器

    装饰器允许传入参数,一个携带了参数的装饰器将有三层函数,如下所示:

    import functools
    
    def log_with_param(text):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                print('call %s():' % func.__name__)
                print('args = {}'.format(*args))
                print('log_param = {}'.format(text))
                return func(*args, **kwargs)
    
            return wrapper
    
        return decorator
        
    @log_with_param("param")
    def test_with_param(p):
        print(test_with_param.__name__)

    看到这个代码是不是又有些疑问,内层的decorator函数的参数func是怎么传进去的?和上面一般的装饰器不大一样啊。
    其实道理是一样的,将其@语法去除,恢复函数调用的形式一看就明白了:

    # 传入装饰器的参数,并接收返回的decorator函数
    decorator = log_with_param("param")
    # 传入test_with_param函数
    wrapper = decorator(test_with_param)
    # 调用装饰器函数
    wrapper("I'm a param")

    输出结果与正常使用装饰器相同:

    call test_with_param():
    args = I'm a param
    log_param = param
    test_with_param

    至此,装饰器这个有点费解的特性也没什么神秘了。
    装饰器这一语法体现了Python中函数是第一公民,函数是对象、是变量,可以作为参数、可以是返回值,非常的灵活与强大。

    原文链接:

    https://www.jianshu.com/p/ee82b941772a
    https://www.geeksforgeeks.org/decorators-in-python/

  • 相关阅读:
    redis 订阅者与发布者(命令行)
    CentOS 6 使用 tptables 打开关闭防火墙与端口
    CentOS 7 使用 firewalld 打开关闭防火墙与端口
    Python面向对象编程-OOP
    python命名规则 PEP8编码规则(约定俗成)
    python 装饰器 概念
    python常用模块 os,datetime,time,MySQLdb,hashlib
    python xml.etree.ElementTree 处理xml 文件 变量 流 xml概念
    Pycharm小技巧
    python概要笔记2
  • 原文地址:https://www.cnblogs.com/HDK2016/p/10973193.html
Copyright © 2011-2022 走看看