0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python:装饰器的原理和案例

如意 来源:百家号 作者: 人工智能研究院 2020-07-01 11:35 次阅读

Python中的装饰器用于扩展可调用对象的功能,而无需修改其结构。基本上,装饰器函数包装另一个函数以增强或修改其行为。我们可以通过一个具体的例子了解基础知识!让我们编写一个包含装饰器实现示例的Python3代码:

装饰定义

defdecorator_func_logger(target_func):defwrapper_func():print(“Before calling”, target_func.__name__) target_func() print(“After calling”, target_func.__name__)return wrapper_funcdef target(): print(‘Python is in the decorated target function’)dec_func = decorator_func_logger(target)dec_func()Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘target’)Python isin the decorated target function(‘After calling’, ‘target’)

上面的装饰器结构有助于我们在调用目标函数之前和之后在控制台上显示一些注释。

以下是定义装饰器的简单步骤;

首先,我们应该定义一个可调用对象,例如装饰器函数,其中还包含一个包装器函数。

装饰器函数应将目标函数作为参数

并且它应该返回包装函数,该包装函数扩展了作为参数传递的目标函数。

包装函数应包含目标函数调用以及扩展目标函数行为的代码。

defdecorator_func_logger(target_func):defwrapper_func(): print(“Before calling”, target_func.__name__) target_func() print(“After calling”, target_func.__name__)return wrapper_func@decorator_func_loggerdef target():print(‘Python is in the decorated target function’)target()Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘target’)Python isin the decorated target function(‘After calling’, ‘target’)

借助Python提供的语法糖,我们可以简化装饰器的定义,如上所示。

请注意,@ decorator_func_logger仅在我们要装饰的目标函数之前添加。然后,我们可以直接调用目标函数。就像我们在第一个实例中所做的那样,无需显式分配装饰器。

定义多个装饰器并使用参数装饰函数

import timedef decorator_func_logger(target_func):defwrapper_func(*args, **kwargs):print(“Before calling”, target_func.__name__) target_func(*args, **kwargs)print(“After calling”, target_func.__name__)return wrapper_funcdef decorator_func_timeit(target_func):defwrapper_func(*args, **kwargs): ts = time.time() target_func(*args, **kwargs) te = time.time()print (target_func.__name__, (te - ts) * 1000)return wrapper_func@decorator_func_logger@decorator_func_timeitdef target(loop): count = 0 print(‘Python is in the decorated target function’)for number in range(loop): count += numbertarget(100)target(3000)Output:air-MacBook-Air:$ python DecoratorsExample.py(‘Before calling’, ‘wrapper_func’)Python isin the decorated target function(‘target’, 0.015974044799804688)(‘After calling’, ‘wrapper_func’)(‘Before calling’, ‘wrapper_func’)Python isin the decorated target function(‘target’, 0.47397613525390625)(‘After calling’, ‘wrapper_func’)

通过使用‘@’语法在目标函数之前添加多个装饰器,可以轻松地用多个装饰器装饰目标函数。装饰器的执行顺序将与在目标函数之前列出的顺序相同。

请注意,我们的目标函数中有一个参数loop。只要包装函数使用相同的参数,就没有问题。为了确保装饰器可以灵活地接受任意数量的参数,将(* args,** kwargs)参数用于包装函数。

重要要点

装饰器定义可重用的代码块,您可以将这些代码块应用于可调用对象(函数,方法,类,对象),以修改或扩展其行为,而无需修改对象本身。

请考虑您的脚本中有许多函数执行许多不同的任务,并且需要向所有函数添加特定的行为。在这种情况下,将相同的代码块复制到函数中以具有所需的功能不是一个好的解决方案。您可以简单地装饰函数。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3860

    浏览量

    61303
  • python
    +关注

    关注

    51

    文章

    4668

    浏览量

    83456
  • 调用
    +关注

    关注

    0

    文章

    8

    浏览量

    3169
收藏 人收藏

    评论

    相关推荐

    鸿蒙原生应用开发-ArkTS语言基础类库多线程@Concurrent装饰校验并发函数

    在使用TaskPool时,执行的并发函数需要使用该装饰修饰,否则无法通过相关校验。从API version 9开始,该装饰支持在ArkTS卡片中使用。
    发表于 03-18 10:30

    Python2与Python3的差异

    Python2与Python3是两个不同的版本,它们在语法、功能和性能等方面存在一些差异。下面是对Python2和Python3的详尽、详实、细致的比较,分为以下几个方面: 语法差异
    的头像 发表于 11-23 16:48 337次阅读

    Python装饰器如何增加任务超时退出功能

    功能,该如何做呢? 方法很多,但最简单直接的是使用并发库futures,为了使用方便,我将其封装成了一个装饰器,代码如下: import functools from concurrent
    的头像 发表于 11-01 10:53 179次阅读

    如何写一个简单的装饰

    今天介绍的是一个已经存在十三年,但是依旧不红的库 decorator,好像很少有人知道他的存在一样。 这个库可以帮你做什么呢 ? 其实很简单,就是可以帮你更方便地写python装饰器代码,更重
    的头像 发表于 11-01 09:54 268次阅读
    如何写一个简单的<b class='flag-5'>装饰</b>器

    OpenHarmony状态变量更改通知:@Watch装饰

    @Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。 说明: 从API version 9开始,该装饰支持在ArkTS卡片
    发表于 10-31 17:45

    Python 自制简单实用的日志装饰

    在写代码的时候,往往会漏掉日志这个关键因素,导致功能在使用的时候出错却无法溯源。 其实,只需要写一个非常简单的日志装饰器,我们就能大大提升排查问题的效率。 1.简陋版装饰器 写一个装饰器非常简单
    的头像 发表于 10-31 15:05 294次阅读
    <b class='flag-5'>Python</b> 自制简单实用的日志<b class='flag-5'>装饰</b>器

    Python自制简单实用的日志装饰

    在写代码的时候,往往会漏掉日志这个关键因素,导致功能在使用的时候出错却无法溯源。 其实,只需要写一个非常简单的日志装饰器,我们就能大大提升排查问题的效率。 1.简陋版装饰器 写一个装饰器非常简单
    的头像 发表于 10-21 14:39 313次阅读
    <b class='flag-5'>Python</b>自制简单实用的日志<b class='flag-5'>装饰</b>器

    装饰器模式和代理模式的区别

    什么是装饰器模式 装饰器模式(Decorator Pattern): 在不改变对象自身的基础上,在程序运行期间给对象动态的添加职责; 感觉和继承如出一辙,不改变父类,子类可拓展功能; 优点 装饰
    的头像 发表于 10-08 14:25 490次阅读
    <b class='flag-5'>装饰</b>器模式和代理模式的区别

    【中秋国庆不断更】OpenHarmony嵌套类对象属性变化:@Observed装饰和@ObjectLink装饰

    上文所述的装饰仅能观察到第一层的变化,但是在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们
    发表于 09-27 16:26

    【中秋国庆不断更】OpenHarmony后代组件双向同步,跨层级传递:@Provide装饰和@Consume装饰

    。 说明: 从API version 9开始,这两个装饰支持在ArkTS卡片中使用。 概述 @Provide/@Consume装饰的状态变量有以下特性: ● @Provide装饰的状
    发表于 09-27 16:21

    OpenHarmony装饰指定自定义组件:@BuilderParam装饰

    引入了@BuilderParam装饰,@BuilderParam用来装饰指向@Builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰
    发表于 09-27 16:02

    OpenHarmony自定义构建函数:@Builder装饰

    开始,该装饰支持在ArkTS卡片中使用。 装饰器使用说明 自定义组件内自定义构建函数 定义的语法: @builder MyBuilderFunction() { ... } @Builder
    发表于 09-26 16:36

    如何使用Python包装正确构建OpenVINO工具套件

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/openvino/bin/intel64/Release/ 测试 构建。运行 以下脚本以导入内核,检查您是否正确构建了 Python* 包装
    发表于 08-15 07:13

    Python装饰器的使用

    定义 首先我们先来了解下装饰器的定义。顾名思义,在Python中,装饰器本质上就是一个函数,它可以接收一个函数作为参数,然后返回一个新的函数。这个新的函数可以在执行原有函数之前或之后,对函数进行一些
    的头像 发表于 06-21 16:54 550次阅读

    分享一个有趣的LED装饰项目

    在本文中,我们将讨论一个如此有趣的LED装饰项目,该项目将模仿旋转的照明脉轮灯。这些可以在流行的上帝偶像的冠冕后面看到,如甘尼萨勋爵、赛巴巴,以及毗湿奴神的手指周围。
    的头像 发表于 06-20 17:24 283次阅读
    分享一个有趣的LED<b class='flag-5'>装饰</b>项目