首页 > 编程语言 >python:揭开装饰器的神秘面纱

python:揭开装饰器的神秘面纱

时间:2024-07-16 12:54:48浏览次数:20  
标签:__ 揭开 python 面纱 func time 装饰 def 函数

一. 前言:揭开装饰器的神秘面纱

装饰器,这个在Python中以@符号开头的神奇存在,实际上是一种函数,用于包装其他函数,以扩展其功能,而不改变其内部逻辑。想象一下,就像给你的咖啡加糖不改其本质,但让它更加甜蜜。内置装饰器如@staticmethod@classmethod,便是装饰器的日常示例,它们负责调整方法的行为,而不用修改方法的定义。

二. 基本语法:构建你的第一个装饰器

简单装饰器的构造

编写装饰器,本质上就是定义一个接收函数作为参数的函数,再返回一个新的函数。比如,一个打印执行时间的装饰器:

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} executed in {end_time - start_time} seconds.")
        return result
    return wrapper

@timing_decorator
def my_slow_function():
    time.sleep(2)
    print("Function executed.")

my_slow_function()

在这个例子中,timing_decorator就是一个装饰器,它记录了被装饰函数的执行时间,并在执行后打印出来。

三. 使用装饰器:点石成金的@

通过@符号,我们能直观且简洁地应用装饰器。这背后,Python解释器替我们完成了函数到装饰器的调用,并把原始函数替换为装饰器返回的新函数。看似一行简单的语法糖,实则隐藏着函数的高级运用,让代码更干净、更模块化。

四. 进阶:带参数的装饰器

有时,我们需要根据情况定制装饰器行为。这时候,带参数的装饰器便闪亮登场。以下是一个可重复执行函数的装饰器示例:

def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat

@repeat(3)
def greet(name):
    print(f"Hello, {name}")

greet("Alice")

在上述代码中,repeat装饰器接受一个参数num_times,然后返回一个真正用于装饰的内部函数,使得greet函数被调用了三次。

五. 类装饰器:另一种维度的魔法

除了函数装饰器,Python还允许使用类作为装饰器。类装饰器利用类的初始化和__call__方法来工作,为函数的包装提供了更多的灵活性和状态保持能力。下面的LoggingDecorator类演示了这一概念:

class LoggingDecorator:
    def __init__(self, func):
        self.func = func
    
    def __call__(self, *args, **kwargs):
        print(f"Calling function: {self.func.__name__}")
        return self.func(*args, **kwargs)

@LoggingDecorator
def add(a, b):
    return a + b

print(add(1, 2))

通过这种方式,每次调用add函数前都会先打印一条消息,展示了函数调用的过程。

总结:装饰器的魅力与PlugLink的启示

装饰器以其独特的魅力,丰富了Python的编程范式,使代码更加灵活、易于维护和扩展。正如PlugLink所倡导的模块化设计哲学,装饰器也鼓励我们在编程实践中遵循“开放封闭原则”,即对扩展开放,对修改封闭,从而促进代码的重用与系统的可维护性。在未来的编程旅程中,让我们继续挖掘装饰器更深层次的应用,同时也不忘探索如PlugLink这样的开源项目,如何能进一步优化我们的开发流程,提升生产力。

标签:__,揭开,python,面纱,func,time,装饰,def,函数
From: https://blog.csdn.net/zhengiqa8/article/details/140463501

相关文章

  • python 基础 之 ipython scrapy shell
    IPython是一个基于Python的交互式计算环境,它为用户提供了一个更为强大和丰富的界面来使用Python语言。相较于标准的Python解释器,IPython提供了更多的增强功能,例如提供智能的自动补全,高亮输出,及其他特性。如果我们安装了IPython,scrapy终端将使用IPython(替代标准Python终端)。......
  • 【Python】指定包的导入路径
    在导入包时,有时会出现已安装但是无法导入的情况,这里记录一下导入包时指定路径的方法,其实就是将其绝对路径添加到环境变量中:命令提示行中提示pyppeteer模块已经安装,在/home/user/.local/lib/python3.9/site-packages路径下:在pycharm中导入pyppeteer提示模块没有安装: 将pypp......
  • Python | 论做游戏外挂,Python输过谁?
    玩过电脑游戏的同学对于外挂肯定不陌生,但是你在用外挂的时候有没有想过如何做一个外挂呢?我打开了4399小游戏网,点开了一个不知名的游戏,唔,做寿司的,有材料在一边,客人过来后说出他们的要求,你按照菜单做好端给他便好~首先要声明,这里的游戏外挂的概念,和那些大型网游里的外挂可不同,......
  • Zmail--让邮件变得简单的python邮件模块
    其他轮子的缺点:服务端拒信:首要问题。很多其他的轮子需要自己构造MIME和邮件头(通常优化了过程),但经常遭遇拒信,具体原因是其没有正确的定义邮件头,诸如From和To的头信息在使用SMTP时每家服务商检查都会有细微的差别,以及一些平台的差异(win10localhost乱码导致发件拒信),甚至在你发往......
  • Python安装出现严重错误的解决方法_0x80070643-( A newer version of the Python laun
    每次在装软件配置环境的时候,总会遇到别人碰不到的各种问题,人都麻了。最后我还是自己尝试这解决了,只是建议,虽然说不知道是否以后还会问题,但是可以成功安装,配置环境并运行。(本人是win11)首先解释一下pythonlauncher是什么资料解释:PythonLauncher是Python官方提供的一个工具,......
  • python 库 Paramiko
    Paramiko说明Paramiko是一个用于在Python中实现SSH协议的模块,它允许你在远程服务器上执行命令、上传和下载文件等操作。Paramiko组件paramiko.Transportparamiko.Transport是用于建立安全通信隧道的类,它是SSH连接的核心部分。它负责与远程服务器建立连接、身份验证和......
  • 【绝命Coding助力秋招】Python实现<实习僧>海投脚本
     hellohello~,这里是绝命Coding——老白~......
  • python 基础之scrapy
    安装:installscrapy#-ihttps://pipy.douban.com/simple不一定好用改其他源码创建scrapy项目的命令:scrapystartproject<项目名字>创建爬虫命令:在项目路径下执行:`scrapygenspider<爬虫名字><允许爬取的域名>`scrapygenspiderbaiduwww.baidu.com运行项目:scra......
  • 数据分享|python分类预测职员离职:逻辑回归、梯度提升、随机森林、XGB、CatBoost、LGB
    全文链接:https://tecdat.cn/?p=34434原文出处:拓端数据部落公众号分析师:ShilinChen离职率是企业保留人才能力的体现。分析预测职员是否有离职趋向有利于企业的人才管理,提升组织职员的心理健康,从而更有利于企业未来的发展。解决方案任务/目标采用分类这一方法构建6种模型对职......
  • python中循环结构
    一、循环分类while循环,for-in遍历循环二、while循环1.while语法结构while 条件表达式:    条件执行体(循环体)2.选择结构的if与循环结构中while的区别if判断一次,条件为true执行一次;while判断n+1次,条件为true,执行n次示例:print('使用if')a=1if(a<10):pri......