聊聊Python中的@符号是什么意思

 更新时间:2021年09月18日 08:57:06   作者:Python学习与数据挖掘  
@符号用做函数的修饰符,可以在模块或者类的定义层内对函数进行修饰,下面这篇文章主要给大家介绍了关于Python中@符号是什么意思的相关资料,需要的朋友可以参考下

Python中的@符号是装饰器的意思。Python中装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)。

  • 实质:是一个函数
  • 参数:是你要装饰的函数名(并非函数调用)
  • 返回:是装饰完的函数名(也不是函数调用)
  • 作用:为已经存在的对象添加额外的功能。
  • 特点:不需要对对象做任何的代码上的变动。

Python装饰器有很多经典的应用场景,比如:插入日志,性能测试,事务处理,权限校验等。装饰器是解决这类问题的绝佳设计。

装饰器最大的作用就是对于我们已经写好的程序,我们可以抽离出一些雷同的代码组件多个特定的装饰器,这样我们就可以针对不同的需求去使用特定的装饰器,这时,因为源码去除了大量泛化的内容而使得源码具有更加清晰的逻辑。

定义一个能打印日志的doctorator:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper


@log
def now():
    print('2021-3-25')


if __name__ == '__main__':
    now()

执行结果:

函数对象有一个__name__属性,可以拿到函数的名字。

调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志。

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

wrapper()函数的参数定义是(*args,**kw),因此,wrapper()函数可以接收任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@log('execute')
def now():
    print('2015-3-25')


if __name__ == '__main__':
    now()

执行结果:

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

now = log('execute')(now)

首先执行log(‘execute'),返回的是decorator函数,再调用返回的函数,参数就是now函数,返回值最终是wrapper函数。

函数也是对象,它有__name_等属性,但你去看经过decorator装饰之后的函数,他们的__name__已经从原来的'now'变成了'wrapper':

print(now.__name__) #输出:wrapper

因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性赋值到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

Python内置的functiontools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

或者

import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

总结

到此这篇关于Python中@符号是什么意思的文章就介绍到这了,更多相关Python中@符号内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • pytorch模型部署 pth转onnx的方法

    pytorch模型部署 pth转onnx的方法

    这篇文章主要介绍了pytorch模型部署 pth转onnx的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • 爬山算法简介和Python实现实例

    爬山算法简介和Python实现实例

    这篇文章主要介绍了爬山算法,爬山法(climbing method)是一种优化算法,其一般从一个随机的解开始,然后逐步找到一个最优解(局部最优)然后用Python实现了这个算法,需要的朋友可以参考下
    2014-04-04
  • 详解在python中如何使用zlib模块进行数据压缩和解压缩

    详解在python中如何使用zlib模块进行数据压缩和解压缩

    Python有一些内置库用于处理数据压缩和解压缩,其中一个就是zlib模块,这个模块为DEFLATE压缩算法和相关的gzip(文件格式)提供了支持,在这篇文章中,我们将深入探讨如何使用zlib模块进行数据压缩和解压缩
    2023-06-06
  • Python matplotlib设置多子图、子图间距及外边距的几种方式

    Python matplotlib设置多子图、子图间距及外边距的几种方式

    子图是Matplotlib中强大的功能之一,使用函数您可以方便地创建多个子图,并使用Axes对象绘制各种图形,下面这篇文章主要给大家介绍了关于Python matplotlib设置多子图、子图间距及外边距的几种方式,需要的朋友可以参考下
    2024-02-02
  • Django如何重置migration的几种情景

    Django如何重置migration的几种情景

    这篇文章主要介绍了Django如何重置migration的几种情景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 详解python:time模块用法

    详解python:time模块用法

    这篇文章主要介绍了python:time模块用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Python中shutil模块的学习笔记教程

    Python中shutil模块的学习笔记教程

    shutil模块是一种高层次的文件操作工具,类似于高级API,主要强大之处在于其对文件的复制与删除操作更是比较支持好。下面这篇文章主要介绍了Python中shutil模块的相关教程,需要的朋友可以参考学习,下面来一起看看吧。
    2017-04-04
  • Elasticsearches之python使用及Django与Flask集成示例

    Elasticsearches之python使用及Django与Flask集成示例

    这篇文章主要为大家介绍了Elasticsearches之python使用及Django与Flask集成示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • 15个Pythonic的代码示例(值得收藏)

    15个Pythonic的代码示例(值得收藏)

    这篇文章主要介绍了15个Pythonic的代码示例(值得收藏),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • python 中 os.walk() 函数详解

    python 中 os.walk() 函数详解

    os.walk()是一种遍历目录数的函数,它以一种深度优先的策略(depth-first)访问指定的目录。这篇文章主要介绍了python 中 os.walk() 函数,需要的朋友可以参考下
    2021-11-11

最新评论