一、装饰器

装饰器:本质就是函数,功能是为其它函数添加附加功能

装饰器的原则:

  • 不修改被修饰函数的源代码
  • 不修改被修饰函数的调用方式

装饰器的知识储备:

  装饰器 = 高阶函数 + 函数嵌套 + 闭包

二、高阶函数

高阶函数的定义:

  • 函数的接收参数是一个函数名
  • 函数的返回值是一个函数名
  • 满足上述条件任意一个都可以是高阶函数
  1. import time
  2.  
  3. def fun1():
  4. time.sleep(0.5)
  5. print("hello")
  6.  
  7. def computing_run_time(fun):
  8. """
  9. 计算函数运行时间
  10. :param fun:
  11. :return:
  12. """
  13. start_time = time.time()
  14. fun()
  15. end_time = time.time()
  16. print("运行时间%s" % (end_time - start_time))
  17.  
  18. computing_run_time(fun1)
  19.  
  20. """
  21. 优点:在不修改函数源代码的前提下,给函数添加了额外的功能
  22. 缺点:改变了调用方式
  23. """

函数的接收参数是函数名

  1. import time
  2.  
  3. def fun1():
  4. time.sleep(0.5)
  5. print("hello")
  6.  
  7. def computing_run_time(fun):
  8. """
  9. 计算函数运行时间
  10. :param fun:
  11. :return:
  12. """
  13. fun()
  14. return fun
  15.  
  16. fun1 = computing_run_time(fun1)
  17. fun1()
  18.  
  19. """
  20. 优点:没有改变函数的调用方式
  21. 缺点:不能为函数添加新的功能
  22. """

函数的返回值是函数名

注:仅仅是高阶函数不能满足装饰器的需求

三、函数嵌套和闭包

  1. """
  2. 闭包:首先必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用
  3.  
  4. 定义:内部函数的代码包含对外部函数的代码的引用,但一定不是对全局作用域的引用
  5. """
  6.  
  7. def fun1():
  8.  
  9. print("fun1")
  10. name = 1
  11.  
  12. def fun2():
  13. print("fun2")
  14. print(name)
  15.  
  16. def fun3():
  17. print("fun3")
  18. print(name)
  19. fun3()
  20. fun2()
  21.  
  22. fun1()

  

四、装饰器示例

无参装饰器

  1. def outer(fun):
  2.  
  3. def wrapper():
  4. fun()
  5.  
  6. return wrapper

加上参数

  1. def outer(fun):
  2.  
  3. def wrapper(*args, **kwargs):
  4. fun(*args, **kwargs)
  5.  
  6. return wrapper

  

简单装饰器

  1. import time
  2.  
  3. def outer(func):
  4. """
  5. 计算程序的运行时间
  6. :param func:
  7. :return:
  8. """
  9.  
  10. def wrapper(*args, **kwargs):
  11. start_time = time.time()
  12. result = func(*args, **kwargs)
  13. stop_time = time.time()
  14. print("函数运行的时间为:%s" % (stop_time-start_time))
  15. return result
  16. return wrapper
  17.  
  18. @outer # 语法糖 等价于 : cal = outer(cal) 把wrapper函数的函数地址赋值给cal
  19. def cal(list1):
  20. result = 0
  21. for i in list1:
  22. time.sleep(0.1)
  23. result += i
  24.  
  25. return result
  26.  
  27. res = cal(range(20))
  28. print(res)

  

注:

  函数cal的执行流程,先执行装饰器的outer函数,outer将函数的返回值赋值给变量cal,所以调用cal()  等价于  cal = outer(cal),   cal()  等价于这两步

多层装饰器

装饰器中含有函数参数

  1. def before(name):
  2. print("before:%s" % name)
  3. return "before"
  4.  
  5. def after(name):
  6. print("after:%s" % name)
  7. return "after"
  8.  
  9. # 外层的参数只是为了将值传递到里层
  10. def outer(before_func, after_func):
  11.  
  12. def middle(main_func):
  13.  
  14. def wrapper(*args, **kwargs):
  15.  
  16. before_result = before_func(*args, **kwargs)
  17. print("before_result:%s" % before_result)
  18.  
  19. main_result = main_func(*args, **kwargs)
  20. print("main_result: %s" % main_result)
  21.  
  22. after_result = after_func(*args, **kwargs)
  23. print("after_result: %s" % after_result)
  24.  
  25. return main_result
  26.  
  27. return wrapper
  28.  
  29. return middle
  30.  
  31. @outer(before, after)
  32. def index(name):
  33. print("index")
  34. return name
  35.  
  36. result = index("aaa")
  37. print(result)

  

python学习【第五篇】python函数 (二)的更多相关文章

  1. Python学习【第九篇】函数

    函数 函数是什么? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上而下实现功能,其往往用一段代码来实现指定功能,开发过 ...

  2. Python 学习 第八篇:函数2(参数、lamdba和函数属性)

    函数的参数是参数暴露给外部的接口,向函数传递参数,可以控制函数的流程,函数可以0个.1个或多个参数:在Python中向函数传参,使用的是赋值方式. 一,传递参数 参数是通过赋值来传递的,传递参数的特点 ...

  3. Python 学习 第七篇:函数1(定义、调用和变量的作用域)

    函数是把一些语句集合在一起的程序结构,用于把复杂的流程细分成不同的组件,能够减少代码的冗余.代码的复用和修改代码的代价. 函数可以0个.1个或多个参数,向函数传递参数,可以控制函数的流程.函数还可以返 ...

  4. Python 学习 第五篇:语句和语法

    Python程序是语句构成的,语句包含表达式,表达式嵌套在语句中,包含变量和常量,用于处理对象.Python的语法实质上是由表达式.语句和代码块构成的.语句是由表达式构成的,代码块是由多个语句构成的复 ...

  5. Python学习第五篇——如何访问字典

    # the example_1 aim to tell how to use dctionary,and how to access list or dictionary infos={"f ...

  6. Python学习笔记基础篇——总览

    Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...

  7. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

  8. 第五篇python进阶之深浅拷贝

    目录 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 二.拷贝(只针对可变数据类型) 三.浅拷贝 四.深拷贝 第五篇python进阶之深浅拷贝 一.引言 1.1可变 和不可变 id不 ...

  9. 第五篇.python进阶

    目录 第五篇.python进阶 1. 异常处理 2. 数字类型内置方法 2.定义: 3.常用操作+内置方法: 4.存一个值or多个值: 5.有序or无序: 6.可变和不可变 1.用途: 2.定义: 3 ...

  10. Python 学习 第十篇 CMDB用户权限管理

    Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...

随机推荐

  1. Ajax库的编写及使用

    ajax使用在服务器端. ajax.js function ajax(url,fnSucc,fnFail) { //1.创建ajax对象 var oAjax = null; if(window.XML ...

  2. C#开发微信公众平台-就这么简单(转载)

    写在前面 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件响应) 示例Demo下载 后记 最近公司在做微信开发,其实就是接口开发,网上找了很多资料,当然园友也写 ...

  3. MPTCP 源码分析(三) 子路径选择

    简述:      支持MPTCP的链路中存在多条子路径,因此在发送数据的时候需要选择最优路径来进行操作. MPTCP利用内核通知链对MPTCP中各子路径进行增加路径.删除路径.修改路径优先级的操作.M ...

  4. Ios 调用Appstore 下载界面 [[UIApplication sharedApplication] openURL

    http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?mt=8&id=286274367 id = itunesconn ...

  5. 使用 原生js 制作插件 (javaScript音乐播放器)

    1.引用页面 index.html <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  6. Linux下Jenkins+git+gradle持续集成环境搭建

    Linux下Jenkins+git+gradle持续集成环境搭建 来源:IT165收集  发布日期:2014-08-22 21:45:50 我来说两句(0)收藏本文   一.项目介绍 和 linux ...

  7. win10 rabbitMQ的安装与测试

    安装 1.首先,下载并运行Erlang for Windows 安装程序 (地址:http://www.erlang.org/downloads)下载完毕并安装(注意:安装目录请选择默认目录) 2.下 ...

  8. flink checkpoint 源码分析 (一)

    转发请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/8029356.html checkpoint是Flink Fault Tolerance机制的重要构成 ...

  9. spring boot 打包报错

    [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.0.RELEASE:repac ...

  10. eclipse 断点类别

    行断点 行断点位于一般方法内,双击代码行左边就可以设置行断点: 行断点可以设置条件,右键断点-properties: 1设置效果是第几次到达时暂停,图中所示是当第三次到达时暂停 2是开启条件断点 3是 ...