iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python如何使用wrapt模块编写更扁平的装饰器
  • 809
分享到

python如何使用wrapt模块编写更扁平的装饰器

2024-04-02 19:04:59 809人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍了python如何使用wrapt模块编写更扁平的装饰器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用 wrapt 模块编

这篇文章主要介绍了python如何使用wrapt模块编写更扁平的装饰器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

使用 wrapt 模块编写更扁平的装饰器

在写装饰器的过程中,你有没有碰到过什么不爽的事情?不管你有没有,反正我有。我经常在写代码的时候,被下面两件事情搞得特别难受:

1. 实现带参数的装饰器时,层层嵌套的函数代码特别难写、难读

2. 因为函数和类方法的不同,为前者写的装饰器经常没法直接套用在后者上

比如,在下面的例子里,我实现了一个生成随机数并注入为函数参数的装饰器。

import random
def provide_number(min_num, max_num):
    """装饰器:随机生成一个在 [min_num, max_num] 范围的整数,追加为函数的第一个位置参数
    """
    def wrapper(func):
        def decorated(*args, **kwargs):
            num = random.randint(min_num, max_num)
            # 将 num 作为第一个参数追加后调用函数
            return func(num, *args, **kwargs)
        return decorated
    return wrapper
@provide_number(1, 100)
def print_random_number(num):
    print(num)
# 输出 1-100 的随机整数
# OUTPUT: 72
print_random_number()
@provide_number 装饰器功能看上去很不错,但它有着我在前面提到的两个问题:嵌套层级深、无法在类方法上使用。如果直接用它去装饰类方法,会出现下面的情况:
class Foo:
    @provide_number(1, 100)
    def print_random_number(self, num):
        print(num)
# OUTPUT: <__main__.Foo object at 0x104047278>
Foo().print_random_number()

Foo 类实例中的 print_random_number 方法将会输出类实例 self ,而不是我们期望的随机数 num。

之所以会出现这个结果,是因为类方法(method)和函数(function)二者在工作机制上有着细微不同。如果要修复这个问题,provider_number 装饰器在修改类方法的位置参数时,必须聪明的跳过藏在 *args 里面的类实例 self 变量,才能正确的将 num 作为第一个参数注入。

这时,就应该是 wrapt 模块闪亮登场的时候了。wrapt 模块是一个专门帮助你编写装饰器的工具库。利用它,我们可以非常方便的改造 provide_number 装饰器,完美解决“嵌套层级深”和“无法通用”两个问题,

import wrapt
def provide_number(min_num, max_num):
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        # 参数含义:
        #
        # - wrapped:被装饰的函数或类方法
        # - instance:
        #   - 如果被装饰者为普通类方法,该值为类实例
        #   - 如果被装饰者为 claSSMethod 类方法,该值为类
        #   - 如果被装饰者为类/函数/静态方法,该值为 None
        #
        # - args:调用时的位置参数(注意没有 * 符号)
        # - kwargs:调用时的关键字参数(注意没有 ** 符号)
        #
        num = random.randint(min_num, max_num)
        # 无需关注 wrapped 是类方法或普通函数,直接在头部追加参数
        args = (num,) + args
        return wrapped(*args, **kwargs)
    return wrapper
<... 应用装饰器部分代码省略 ...>
# OUTPUT: 48
Foo().print_random_number()

使用 wrapt 模块编写的装饰器,相比原来拥有下面这些优势:

• 嵌套层级少:使用 @wrapt.decorator 可以将两层嵌套减少为一层

• 更简单:处理位置与关键字参数时,可以忽略类实例等特殊情况

• 更灵活:针对 instance 值进行条件判断后,更容易让装饰器变得通用

感谢你能够认真阅读完这篇文章,希望小编分享的“Python如何使用wrapt模块编写更扁平的装饰器”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网Python频道,更多相关知识等着你来学习!

--结束END--

本文标题: python如何使用wrapt模块编写更扁平的装饰器

本文链接: https://www.lsjlt.com/news/95293.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python如何使用wrapt模块编写更扁平的装饰器
    这篇文章主要介绍了python如何使用wrapt模块编写更扁平的装饰器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用 wrapt 模块编...
    99+
    2024-04-02
  • 如何使用Python的装饰器
    这篇文章将为大家详细讲解有关如何使用Python的装饰器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.定义及使用例1:装饰器定义:      def 装饰器函数(外部函数...
    99+
    2023-06-29
  • 如何使用Python装饰器实现单例模式
    这篇文章主要为大家展示了“如何使用Python装饰器实现单例模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用Python装饰器实现单例模式”这篇文章吧。装饰器实现:def w...
    99+
    2023-06-17
  • Python中如何使用装饰器?
    类方法和静态方法有点相似,他们都推荐使用类来调用(其实也可以使用对象来调用) 定义类方法 —使用@classmetho修饰(函数装饰器) —方法的第一个参数定义为cls(class的缩写),用类调用该方法时该参数会自动绑定 定义静...
    99+
    2023-01-31
    如何使用 Python
  • 如何使用Python装饰器Decorator
    本篇内容介绍了“如何使用Python装饰器Decorator”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 1. 叠加使用Pyth...
    99+
    2023-06-15
  • PHP中如何使用装饰器模式?
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-21
  • 如何使用C/C++编写node.js原生模块
    这篇文章主要为大家展示了“如何使用C/C++编写node.js原生模块”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用C/C++编写node.js原生模块...
    99+
    2024-04-02
  • 基于Python编写简单实用的日志装饰器
    目录1.简陋版装饰器2.普通版装饰器3.优化版装饰器在写代码的时候,往往会漏掉日志这个关键因素,导致功能在使用的时候出错却无法溯源。 其实,只需要写一个非常简单的日志装饰器,我们就能...
    99+
    2024-04-02
  • 如何使用 pip 安装 Python MySQLdb 模块?
    要安装Python MySQLdb模块,我们需要安装Python当前版本,即3.7 我们需要找到 pip 命令所在的 Python 脚本的位置。首先,打开cmd并到达Python脚本的位置。 要打开 cmd,请按“Windows+R”并键入...
    99+
    2023-10-22
  • 如何使用Python中的装饰器函数
    如何使用Python中的装饰器函数在Python编程中,装饰器(decorators)是一种非常有用的工具。它允许我们在不修改原始函数代码的情况下,对函数进行额外的功能扩展。装饰器函数可以在函数执行前后自动执行一些操作,例如记录日志、计时、...
    99+
    2023-10-22
    Python 使用 装饰器函数
  • 如何在Python 中使用@lazyprop 装饰器
    本篇文章为大家展示了如何在Python 中使用@lazyprop 装饰器,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。安装pip install lazyprop例子1from&...
    99+
    2023-06-15
  • 如何在Python中使用@property装饰器
    这期内容当中小编将会给大家带来有关如何在Python中使用@property装饰器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、property() 函数讲解了解 @property 装饰器之前,我们...
    99+
    2023-06-15
  • python如何引用自己写的模块
    要引用自己写的模块,可以按照以下步骤进行操作:1. 在你的模块所在的文件夹中创建一个空白的`__init__.py`文件。这个文件是...
    99+
    2023-09-25
    python
  • 如何在python中使用类装饰器
    这篇文章将为大家详细讲解有关如何在python中使用类装饰器,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python有哪些常用库python常用的库:1.requesuts;2.scrap...
    99+
    2023-06-14
  • 如何进行Python函数装饰器的使用
    如何进行Python函数装饰器的使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。装饰器装饰器的定义关于装饰器的定义,我们先来看一段github上大佬的定义:Functio...
    99+
    2023-06-26
  • 详解Java如何优雅的使用装饰器模式
    目录什么是装饰器模式优点缺点使用场景装饰器模式和代理模式的区别装饰器的简单实现装饰器模式实战小结什么是装饰器模式 装饰器模式(Decorator Pattern): 在不改...
    99+
    2024-04-02
  • python的argparse模块如何使用
    这篇文章主要介绍“python的argparse模块如何使用”,在日常操作中,相信很多人在python的argparse模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python的argparse...
    99+
    2023-07-05
  • Python的Schedule模块如何使用
    这篇“Python的Schedule模块如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python的Schedule...
    99+
    2023-06-30
  • python如何使用类来实现装饰器
    这篇文章主要介绍python如何使用类来实现装饰器,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!尝试用类来实现装饰器绝大多数装饰器都是基于函数和 闭包 实现的,但...
    99+
    2024-04-02
  • Vue中的装饰器如何使用
    小编给大家分享一下Vue中的装饰器如何使用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!相信各位在开发中一定遇到过二次弹框确认相关的需求。不管你使用的是UI框架的...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作