博客
关于我
【python】装饰器(1)
阅读量:754 次
发布时间:2019-03-22

本文共 1931 字,大约阅读时间需要 6 分钟。

介绍

装饰器(Decorators)是 Python 中一个核心概念,用于扩展和修改可调用对象的行为,而无需修改其本身。装饰器通过在包装对象运行之前或之后执行代码来增强功能,这使得我们的代码更加简洁高效。装饰器在实际应用中广泛使用,例如日志记录、性能测试、身份验证、授权、计时和缓存等场景。

装饰器用法

Python 提供了 @ 符号作为装饰器的简化语法,但需要注意,装饰器函数必须返回一个函数对象。我们可以分为两种类型:不带 @ 符号和带 @ 符号的装饰器。

不带 @ 符号的 Python 装饰器

在这种情况下,我们手动定义一个装饰器函数,然后使用它来包装目标函数。例如:

def a(func):    def wrapper():        print("11111")        func()        print("22222")    return wrapper# 调用def b():    print("bbbbbbb")# 调用方式需要通过执行 a(b) 来访问 func

这里,a 作为装饰器,通过在输出中添加两行打印来装饰函数 b 的行为,打印了 "11111" 和 "22222",随后调用 b。

带 @ 符号的 Python 装饰器

使用 @ 符号时,可以简化装饰器的书写方式,并且在定义装饰器后直接应用于目标函数。例如:

def a(func):    def wrapper():        print("11111")        func()        print("22222")    return wrapper@decorator adef b():    print("bbbbbbb")

此时,b 函数已经被装饰,直接调用 b() 就会触发装饰后的行为。

functools @wraps 装饰器

在应用装饰器后,函数名、文档字符串和 module 等属性会丢失,这对于调试和维护来说是个问题。为了保留这些属性,我们可以使用 functools 中的 @wraps 装饰器。例如:

from functools import wrapsdef a(fun):    @wraps(fun)    def wrapper():        '''这是 wrapper 函数的文档字符串'''        print("***************************")        fun()        print("***************************")    return wrapper@decorator adef b():    '''这是 b 函数的文档字符串'''    print("bbbb")    # 调用 b 的结果    print(b.__name__)    print(b.__doc__)

通过使用 @wraps 装饰器,函数的元数据(如名称、文档字符串)得以保留,这简化了调试和维护过程。

Python 类装饰器

类装饰器是一种更加灵活的装饰器类型,我们可以自定义类并提供额外功能。例如,可以创建一个计数器装饰器来跟踪函数的调用次数。具体实现如下:

from functools import update_wrapperclass CountCalls:    def __init__(self, fun):        update_wrapper(self, fun)        self.fun = fun        self.num_of_calls = 0    def __call__(self, *args, **kwargs):        self.num_of_calls += 1        print(f"Call {self.num_of_calls} of {self.fun.__name__}")        return self.fun(*args, **kwargs)@CountCallsdef hello():    print("Hello there!")# 示例调用a = hello()print(f"函数 {hello.__name__} 被调用了 {a.num_of_calls} 次")b = hello()print(f"函数 {hello.__name__} 被调用了 {b.num_of_calls} 次")

在这种方式下,CountCalls 类作为装饰器,自动跟踪和打印目标函数的调用次数。这为代码的监控和调试提供了强大的功能。

转载地址:http://oplwk.baihongyu.com/

你可能感兴趣的文章
Python在def函数中使用for循环
查看>>
Python在def函数中使用for循环
查看>>
Python在Conda环境中,但在Windows虚拟环境中没有激活
查看>>
python系列【仅供参考】:python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
查看>>
python图像条状状噪声,使用PYTHON PIL从验证码图像中删除背景嘈杂的线条
查看>>
Python图像处理:从内存加载jpeg
查看>>
python固定后缀(名物化词汇)词频统计:抽取+统计+可视化
查看>>
python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
查看>>
python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载
查看>>
python商品库存管理系统 django框架 商品网站 MySQL数据库 源码下载 计算机毕业设计
查看>>
Python哪个版本最稳定好用2023.10.19
查看>>
Python和黑客技术的渊源
查看>>
Python和RF编写接口自动化
查看>>
Python和RF编写web自动化
查看>>
python和js哪个难_【Python】记一次学习,Python 与 js 在实现闭包时的差异
查看>>
python和java哪个更值得学——来自知乎高赞回答
查看>>
python和c混合编程 github_在pycharm中使用git版本管理以及同步github的方法
查看>>
python命名空间更改_Python模块xml.etree.ElementTree自动修改xml命名空间键
查看>>
Python命名中尾随下划线有什么好处?
查看>>
Python启动脚本
查看>>