聊聊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中@符号内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python数据可视化实现正态分布(高斯分布)

    Python数据可视化实现正态分布(高斯分布)

    这篇文章主要介绍了Python数据可视化实现正态分布(高斯分布),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • python+requests实现接口测试的完整步骤

    python+requests实现接口测试的完整步骤

    这篇文章主要给大家介绍了关于python+requests实现接口测试的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • django rest framework serializer返回时间自动格式化方法

    django rest framework serializer返回时间自动格式化方法

    这篇文章主要介绍了django rest framework serializer返回时间自动格式化方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python神器之使用watchdog监控文件变化

    Python神器之使用watchdog监控文件变化

    这篇文章主要为大家详细介绍了Python中的神器watchdog以及如何使用watchdog监控文件变化,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2023-12-12
  • python网络爬虫基本语法详解

    python网络爬虫基本语法详解

    掌握Python网络爬虫基本语法,就是打开数据世界的钥匙,在这份指南中,我们将带你深入浅出,从零开始一步步变成抓取信息的高手,准备好探索无限可能的网络数据世界了吗?让我们一起开启这段精彩旅程吧!
    2024-03-03
  • python开发游戏的前期准备

    python开发游戏的前期准备

    在本篇文章中我们给大家分享了关于python开发游戏的前期准备以及用到的工具等内容,需要的朋友们跟着参考下。
    2019-05-05
  • python随机模块random使用方法详解

    python随机模块random使用方法详解

    这篇文章主要介绍了python随机模块random使用方法详解,需要的朋友可以参考下
    2020-02-02
  • 一文详解Python加解压文件gzip库的操作

    一文详解Python加解压文件gzip库的操作

    Gzip是若干种文件压缩程序的简称,通常指GNU计划的实现。本文为大家介绍了Python中加解压文件gzip库的基本操作,感兴趣的小伙伴可以了解一下
    2022-11-11
  • python tkinter GUI绘制,以及点击更新显示图片代码

    python tkinter GUI绘制,以及点击更新显示图片代码

    这篇文章主要介绍了python tkinter GUI绘制,以及点击更新显示图片代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python中集合的内建函数和内建方法学习教程

    Python中集合的内建函数和内建方法学习教程

    这篇文章主要介绍了Python中集合的内建函数和内建方法学习教程,包括工厂函数和仅用于可变集合的方法等知识点,需要的朋友可以参考下
    2015-08-08

最新评论