当前位置: 首页 > news >正文

Python中的“@”,有什么用?

前言

在Python中,@ 符号确实扮演了一个极其重要且富有创意的角色,它以一种优雅的方式引入了“装饰器”(Decorators)这一强大概念,堪称Python编程语言的“语法糖”典范。装饰器不仅增强了代码的可读性和复用性,还允许开发者在不修改原有函数或类定义的情况下,为它们添加新的功能。接下来,我们将深入剖析装饰器的工作原理,并通过一系列示例代码来直观展示其强大之处,从而帮助您更好地理解和运用这一Python特性。
在这里插入图片描述

正文

要知道,在Python中,@ 符号独具特色地应用于函数定义之前,这一机制被巧妙地命名为“装饰器”。装饰器为Python编程带来了极大的灵活性和便利性,它允许开发者以一种非侵入式的方式,为函数或方法增添额外的功能或修改其行为,而无需直接修改函数本身的代码。

举个例子,如下所示:


@print
def say_hello():print("Hello, world!")say_hello()

当成功运行上述代码之后,输出结果如下所示:

<function say_hello at 0x7f6a1c0c8940>

出现上面的情况是什么原因造成的呢?需要注意的是,这里的@print其实是将say_hello函数“装饰”或“包装”了一层print。换言之,这里的say_hello=print(say_hello)被隐藏的执行了。

有同学可能会问,既然用到装饰器,那它的内部机制的工作原理是怎么样的呢?

1.定义装饰器的函数;

2.将装饰器应用于目标函数;

3.在运行的时候替换目标函数。

我们以下面的代码为例,示例如下所示:

def uppercase(func):def wrapper(*args, **kwargs):result = func(*args, **kwargs)return result.upper()return wrapper@uppercase
def say_hello(name):return f"hello, {name}"print(say_hello("Alice"))  # HELLO, ALICE

在上述代码中,定义一个装饰器函数 uppercase,该函数旨在接收另一个函数 func 作为参数,并返回一个新的函数 wrapper。通过使用 @uppercase 语法,我们可以优雅地将 uppercase 装饰器应用于任何期望其返回值被转换为大写的函数上,比如 say_hello 函数。这一过程实质上是将 say_hello 函数作为参数传递给 uppercase 函数,并将 uppercase 返回的新函数 wrapper 重新赋值给 say_hello 的标识符。

当执行 say_hello(“Alice”) 调用时,实际上触发的是经过 uppercase 装饰后的 wrapper 函数。wrapper 函数内部会先调用原始的 say_hello 函数,随后将其返回的字符串转换为大写,最后返回这个转换后的结果。通过这种非侵入式的方式,我们在不直接修改 say_hello 函数体的情况下,为其增添了新的功能特性——即自动将输出转换为大写。这正是装饰器模式在Python中展现其强大灵活性的一个典型示例。

接下来,我们再看看带参数的装饰器。

有的时候,我们需要为装饰器添加一些参数,对此需要怎么去实现呢?我们直接看下面的示例代码:

def repeat(n):def decorator(func):def wrapper(*args, **kwargs):result = func(*args, **kwargs)return result * nreturn wrapperreturn decorator@repeat(3)
def say_hello(name):return f"hello, {name}"print(say_hello("Alice"))  
# hello, Alice hello, Alice hello, Alice

在上面的示例中,repeat 函数扮演了一个“装饰器工厂”的角色,它本身不直接作为装饰器使用,而是根据提供的参数(本例中为重复次数 n)动态生成一个装饰器函数 decorator。这个 decorator 函数随后接受一个目标函数 func 作为参数,并返回一个新的封装函数 wrapper。wrapper 函数的核心职责是在内部调用原始的 func 函数,并巧妙地将 func 的返回值重复 n 次后返回。

利用 @repeat(3) 这样的语法糖,我们得以将 say_hello 函数与 repeat(3) 生成的装饰器无缝结合,实现了一个非侵入式的功能增强:每当调用 say_hello 函数时,其返回的字符串将会被自动重复三次。这一机制展示了装饰器模式在Python中的高度灵活性和强大功能,允许开发者以简洁优雅的方式扩展函数行为。

通过本文,我们深入剖析了Python中@符号背后的内部运作原理与精妙机制。揭示了@符号作为语法糖的本质,它实际上在代码执行前被Python解释器自动转换为一系列函数调用和赋值操作的序列。我们详细阐述了如何定义装饰器函数,展示了如何将装饰器优雅地应用于目标函数之上,并深入探讨了这一过程中如何在运行时动态地替换目标函数的行为。通过这些,可以让你对Python中@符号所蕴含的强大功能与灵活性有更加深刻而全面的认识。

最后 如果你对Python感兴趣的话,可以试试我整理的这份Python全套学习资料,【点击这里】领取!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!
Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独家Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便******

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Tessent】【Command】set_design_level Design Level
  • 【系统架构设计师】二十四、安全架构设计理论与实践⑤
  • 双算法https证书获取指南
  • win10自带dll修复丢失的几种方法,快速修复错误dll文件的方式
  • c++初阶-----STL---list
  • 人力资源杂志人力资源杂志社人力资源编辑部2024年第13期目录
  • 白骑士的PyCharm教学高级篇 3.1 性能分析与优化
  • SQL各种注入详解加案例--持续更新
  • 【数据结构】mapset详解
  • 结构开发笔记(一):外壳IP防水等级与IP防水铝壳体初步选型
  • 六点建议有效防止晶振老化
  • 武汉流星汇聚:亚马逊助力领航跨境蓝海,品牌影响力跃上新台阶
  • YoloV10 论文翻译(Real-Time End-to-End Object Detection)
  • SpringBoot面试题整理(1)
  • 二维码生成原理及解码原理
  • @angular/forms 源码解析之双向绑定
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Golang-长连接-状态推送
  • Intervention/image 图片处理扩展包的安装和使用
  • LeetCode18.四数之和 JavaScript
  • LeetCode29.两数相除 JavaScript
  • leetcode98. Validate Binary Search Tree
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Spring核心 Bean的高级装配
  • Sublime Text 2/3 绑定Eclipse快捷键
  • TCP拥塞控制
  • Transformer-XL: Unleashing the Potential of Attention Models
  • windows下使用nginx调试简介
  • 不上全站https的网站你们就等着被恶心死吧
  • 类orAPI - 收藏集 - 掘金
  • 前端技术周刊 2019-01-14:客户端存储
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 阿里云ACE认证之理解CDN技术
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #window11设置系统变量#
  • #职场发展#其他
  • (1)(1.9) MSP (version 4.2)
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (黑马点评)二、短信登录功能实现
  • (九十四)函数和二维数组
  • (转载)深入super,看Python如何解决钻石继承难题
  • *** 2003
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .NET Framework .NET Core与 .NET 的区别
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .net 按比例显示图片的缩略图
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .net实现客户区延伸至至非客户区