一、装饰器基础

装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。装饰器可能会处理被装饰的函数,然后把他返回,或者将其替换成另一个函数或可调用对象。

eg:decorate装饰器

@decorate
def target():
print("Running target()") #上面写法等同于 def target():
print("Running target()")
target = decorate(target)

两种写法最终得出来的结果相同,但两个代码执行完毕得到的target不一定是原来那个target函数,而是被decorate(target)返回的函数。

1、装饰器通常把函数替换成另一个函数

def deco(func):
def inner():
print('Running inner()')
return inner #deco返回inner函数对象 @deco
def target(): #使用deco装饰target
print('Running target()') >>target() #运行target函数,调用被装饰的target其实会运行inner
Running inner() >>target #审查对象,发现target现在是inner的引用
<function deco.<locals>.inner at 0x10063b598>

装饰器只是一种语法糖,装饰器可以像常规的可调用对象一样调用,其参数是另一个函数。装饰器的一大特性是,能把被装饰的函数替换为其他函数,装饰器在加载模块时会立即执行。

二、何时执行装饰器

装饰器在被装饰的函数定义后会立即执行。

eg:registration.py模块

registry = []    #registry保存被@registry装饰的函数引用

def register(func):    #register的参数是一个函数
print("Running register(%s)" % func) #显示被装饰的函数
registry.append(func) #把func存入registry
return func #返回func:必须返回函数;这里返回的函数与通过参数传入的一样 @register #f1,f2被@register装饰
def f1():
print("Running f1()") @register
def f2():
print("Running f2()") def f3(): #f3没用被装饰
print("Running f3()") def main(): #main显示registry,然后调用f1()、f2()、f3()
print("Running main()")
print("Registry ->",registry)
f1()
f2()
f3() if __name__ == "__main__":
main() #只有把registration.py当作脚本运行时才调用main()

上述代码输出如下:

$python3 registration.py
Running register(<function f1 at 0x1000631bf8>)
Running register(<function f1 at 0x1000631c80>)
Running main()
registry -> [<function f1 at 0x1000631bf8> ,<function f1 at 0x1000631c80>]
Running f1()
Running f2()
Running f3()

加载模块后,register中有两个被装饰函数的引用:f1、f2。这两个函数,以f3,只有在main明确调用它们才执行。

如果导入registration.py模块(不作为脚本运行),输出如下:

import registration
Running register(<function f1 at 0x10063b1e0>)
Running register(<function f2 at 0x10063b237>)

函数装饰器在导入模块时立即执行,而被装饰函数只在明确调用时运行

Python装饰器基础及运行时间的更多相关文章

  1. 使用python装饰器计算函数运行时间的实例

    使用python装饰器计算函数运行时间的实例 装饰器在python里面有很重要的作用, 如果能够熟练使用,将会大大的提高工作效率 今天就来见识一下 python 装饰器,到底是怎么工作的. 本文主要是 ...

  2. Python装饰器基础

    一.Python装饰器引入 讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个 ...

  3. python装饰器基础及应用

    一.简介 装饰器是是修改其它函数功能的函数:其意义是让其他函数在不修改任何代码的前提下增加额外功能 二.数据类型 首先我们来看一段简单的代码: from types import MethodType ...

  4. Python基础(五) python装饰器使用

    这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次 ...

  5. Python开发基础-Day7-闭包函数和装饰器基础

    补充:全局变量声明及局部变量引用 python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 global关键字用来在函数或其 ...

  6. [python 基础]python装饰器(一)添加functools获取原函数信息以及functools.partial分析

    python装饰器学习的时候有两点需要注意一下 1,被装饰器装饰的函数取其func.__name__和func.func_doc的时候得到的不是被修饰函数的相关信息而是装饰器wrapper函数的doc ...

  7. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  8. python 装饰器 一篇就能讲清楚

    装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...

  9. Python 装饰器使用指南

    装饰器是可调用的对象,其参数是另一个函数(被装饰的函数). 1 装饰器基础知识 首先看一下这段代码 def deco(fn): print "I am %s!" % fn.__na ...

随机推荐

  1. 微信小程序获取用户手机号详解

    最近在做一款微信小程序,需要获取用户手机号,具体步骤如下: 流程图: 1.首先,客户端调用wx.login,回调数据了包含jscode,用于获取openid(用户唯一标识)和sessionkey(会话 ...

  2. C#中MemoryStream类的介绍

    MemoryStream位于System.IO命名空间,为系统内存提供流式的读写操作.常作为其他流数据交换时的中间对象操作. 1.MemoryStream类封装一个字节数组,在构造实例时可以使用一个字 ...

  3. numpy 数组对象

    numpy 数组对象NumPy中的ndarray是一个多维数组对象,该对象由两部分组成:实际的数据,描述这些数据的元数据# eg_v1 import numpy as np a = np.arange ...

  4. 在HTML5的 input:file 上传文件类型控制 遇到的问题

    1.input:file 属性的介绍  先瞅代码吧 <form> <input type="file" name="pic" accept=& ...

  5. Gpload安装手册(Linux版本)

    Gpload安装手册(Linux版本) 一.python 2.7版本 Linux系统默认是安装python2.7的,如果没有需要手动安装(python版本要求2.4.4以上): 通过命令:python ...

  6. RESTful API 设计指南-阮一峰

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  7. 剑指offer(1)二维数组的查找

    限制今天起开始也刷剑指offer啦,一步一步来. 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...

  8. SQLServer “无法对数据库'XX' 执行删除,因为它正用于复制”的解决方法

    修改数据库某个字段的长度时出现: “无法修改表.无法对 表'dbo.N_Client_content' 执行 删除,因为它正用于复制.” 不能直接对该数据库进行操作,通过alter 的办法来修改,问题 ...

  9. MySQL 变量类型

    用户定义的变量(前缀为@): 您可以访问任何用户定义的变量,而无需声明或初始化它.如果引用尚未初始化的变量,则其值为NULL和字符串类型. select @now2; NULL set赋值: set ...

  10. idea下使用Git基本操作(转载)

    IDEA中Git的更新.提交.还原方法: https://blog.csdn.net/geng31/article/details/78585557 IDEA中Git的提交到GitHub http:/ ...