一、装饰器基础

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

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. 在CentOS 7中安装与配置Tomcat-8.5方法

    安装说明 安装环境:CentOS-7 安装方式:源码安装 软件:apache-tomcat-8.5.39.tar.gz下载地址:http://tomcat.apache.org/download-80 ...

  2. #WEB安全基础 : HTTP协议 | 0x4 各种协议与HTTP协议的关系(一个报文的旅行)

    报文是怎么旅行的呢? 在网络中有很多引路人,如HTTP协议,IP协议.TCP协议.DNS协议以及ARP协议. 请看下图,演绎一个报文的旅程 这就是一个报文的完整请求过程,请加以理解并记忆 //本系列教 ...

  3. 彻底解决(Microsoft Visual C++ 14.0 is required)的步骤123

    之前要用协程gevent,安装pip install gevent包时遇到Microsoft Visual C++ 14.0 is required的报错提示,各种下载没有解决很头疼, 前两天安装sc ...

  4. Unity之流光效果

    效果如图: shader如下: Shader "Unlit/Walk light" { Properties { _MainTex ("Base (RGB), Alpha ...

  5. MongoDB 知识点

    左边是mongodb查询语句,右边是sql语句.对照着用,挺方便. db.users.find() select * from users db.users.find({"age" ...

  6. LATCH_VARIANT = Magna compile

    after: LATCH_VARIANT = Magna in m_project_cfg.mak of PG_.. 1. first error: SED   tmp__.dep/bin/sh: / ...

  7. JS设计模式(1)单例模式

    什么是单例模式 定义:1.只有一个实例.2.可以全局访问 主要解决:一个全局使用的类频繁地创建与销毁. 何时使用:当您想控制实例数目,节省系统资源的时候. 如何解决:判断系统是否已经有这个单例,如果有 ...

  8. Linux统计系统文件类型出现的次数

    awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab /^UUID/ 匹配确定行范围

  9. Android创建自定义的布局和控件

    Android的自带布局有framelayout.linerlayout.relativelayout,外加两个百分比布局,但是这些无法灵活的满足我们的需要,所以我们要自己自定义并引入自己的布局.首先 ...

  10. 王之泰201771010131《面向对象程序设计(java)》第二周学习总结

    王之泰201771010131<面向对象程序设计(java)>第二周学习总结 第一部分:理论知识学习部分 第三章 第三章内容主要为Java语言的基础语法,主要内容如下 1.基础知识 1.1 ...