python学习之路(九)

这一节主要讲的是装饰器。装饰器是一个非常好用的,用于装饰已有函数的函数功能。

 其优点是不用修改调用方式,还不用修改源代码。

他的思想是:函数既变量;高阶函数;嵌套函数。

 现在来尝试写装饰器

有两个函数 各自实现自己的功能 
每个函数执行的时候 都肯定要消耗时间
那现在 就写一个装饰器 来统计这两个函数的运行时间
 
首先 把这两个函数写好
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
 要注意的是 不可以改变函数的调用方式
test1 函数的调用 —— test1()
test2 函数的调用 —— test2()
 
 怎样才能在不改变函数调用方式的前提下 给函数增加功能呢
首先 要搞一个高阶函数
然后 把函数传给高阶函数 当作参数
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
这样子 运行效果:
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
功能 是加上去了 但是 调用方式也改变了 这样不行
 
 高阶函数还没有用到呢
import time

def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('----------the func run time is %s' %(stop_time-start_time))
return deco


def foo1():
time.sleep(1)
print('----------i am in foo 111----------')


def foo2():
time.sleep(2)
print('----------i am in foo 222----------')


foo1 = timer(foo1)
foo1()

foo2 = timer(foo2)
foo2()
高阶函数 就是在本来已经实现了功能的代码段外面 再套一层
 
本来实现计时功能的代码:
def deco(func):
start_time = time.time()
func()
stop_time = time.time()
print('----------the func run time is %s' %(stop_time-start_time))
外面套一层:
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('----------the func run time is %s' %(stop_time-start_time))
return deco
还有一种语法糖
比方说 timer 是实现了附加功能的代码:
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('----------the func run time is %s' %(stop_time-start_time))
return deco
那现在要给 foo1 函数增加功能 就这样:
@timer
def foo1():
time.sleep(1)
print('----------i am in foo 111----------')
要给 foo2 函数增加功能 就这样:
@timer
def foo2():
time.sleep(2)
print('----------i am in foo 222----------')
最后运行的时候 就像原先的调用方式一样就可以了
foo1()

foo2()
运行结果 功能加上了 同时函数调用方式没有变:
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
7.7 调试方式运行
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
先是导入模块:import time
然后走到下一行 timer 函数的定义:def timer(func):
(因为 python 它是解释执行 所以是按顺序一行一行去执行的)
 
再往下走:函数体没有执行 直接跳到语法糖:
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
因为 def 里面的函数体 它只是一个定义 它没有调用 所以就不执行
 
然后再往下 从语法糖 直接跳到:foo1()
中间的 foo1 函数的定义也不执行 原理跟上面那个 timer 不执行一样
 
foo1() 这句是函数调用 这句调用直接引导到 deco 函数的定义
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
这是为什么呢? —— 因为刚才运行语法糖的时候 它实际上运行的是:
foo1 = timer(foo1)
它实际上就是把 timer 函数 赋值给 foo1 这个变量
所以 foo1 已经被替换成了 timer 所以调用 foo1 的时候 会去执行 timer
 
然后蹦到 def deco() 的时候 它也是一个定义 没有调用 跟上面说过的那样
它不执行中间的函数体 直接跳到 return deco 返回了
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
继续往下走 又走到了 foo1() 这次直接跳到了 deco 函数去执行它 
所以其实执行 test1 函数 就是执行 deco 函数
在执行 deco 函数的时候 先取了一个 start_time
然后执行 func() 函数
第二阶段 7 装饰器小高潮 - Lucia - Lucias WorkShop
 
执行 func() 函数 其实就是执行 foo1() 函数
这是因为 语法糖里面已经把 foo1 作为参数传给了 timer(func) 函数
 
执行 foo1() 函数 就是进入 foo1() 函数的函数体 
先睡 1 秒 然后 print 一行话
 
之后 再取一个 stop_time 然后再 print 一行话 结束


转载于:https://www.cnblogs.com/lovelyming/p/7265661.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/268770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java http请求实现_java工程实现http请求接口

java工程实现http请求接口java工程实现http请求接口1.实现代码package com.home;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.sun.net.httpserver.HttpExchange;import com.sun.net.httpserver.HttpHandler;import com.sun.net.https…

Java集合中removeIf的使用

使用removeIf方法从List中删除元素 在JDK1.8中,Collection以及其子类新加入了removeIf方法,作用是按照一定规则过滤集合中的元素。这里展示removeIf的用法。 需求是过滤掉学生中分数为为18以下的, 一个学生实体类 Data public class Studen…

Java中lombok @Builder注解使用详解

简介 Lombok大家都知道,在使用POJO过程中,它给我们带来了很多便利,省下大量写get、set方法、构造器、equal、toString方法的时间。除此之外,通过Builder注解,lombok还可以方便的实现建造者模式,创建对象 …

Java中Collections.singletonList用法

Collections.singletonList()返回的是不可变的集合,但是这个长度的集合只有1,可以减少内存空间。但是返回的值依然是Collections的内部实现类,同样没有add的方法,调用add,set方法会报错 调用add方法报错 Exception in…

CF Round410 D. Mike and distribution

D. Mike and distribution 构造法 798D - Mike and distribution In the beginning, its quite easy to notice that the condition " 2(ap1  ...  apk) is greater than the sum of all elements in A " is equivalent to " ap1  ...  apk is greater …

ADSL提速 从入门到精通

虽然现在的宽带速率已经很快了,但是大家还是希望在以下方面提升一下应用速度:电影BT下载时、在线影音播放时、FTP文件传送时等。广大网友也因此探寻出不少提升宽带速率的方法,那么,都有哪些简单可行的提速方法呢?它们的…

Swift开发图解入门

《论语卫灵公》有一段经典对白:『子贡问为仁。子曰:工欲善其事,必先利其器。……』。对于一个程序猿来说,好的工具不意味着一定能产生优质的代码。可是好的工具对提升开发效率的作用还是不言而喻的。想要用Swift做iOS开发。唯一可…

java 负数存储结构_负数在java中的存储和读取过程 | 学步园

问题描述:将-5存储在文本文件中,再读取出来显示到控制台;预备知识:1.在java中使用补码处理数字,而且byte(8)的数字在扩展成int(32)类型的时候,正数填充0,负数填充1;2.负数的转变过程,正数的原码…

一升的眼泪 日记原文+剧照

作者 木藤亚也14岁——我的家人  “我不能活动,可是我想活着……”   然而,我怎么也想不到,就在我生日这一天,却发生了一场悲剧——玛丽被邻居家养的大狗“老虎”咬破头,死了。玛丽虽然身体小小的&#x…

mysql+phpmyadmin配置流程

mysqlphpmyadmin配置流程:环境:Apachephp5mysql5下载包:phpMyAdmin-2.11.9.4-all-languages-utf-8-only.tar.gz不能下就到这里下载 [url]http://www.phpmyadmin.net/home_page/downloads.php[/url]一:安装配置1> 安装包&#x…

form表单多文件上传

1.html/jsp主页 <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"…

JS学习记录(BOM部分)

BOOM部分 Screen <html lang"en"> <head><meta charset"UTF-8"><title>Screen</title> </head> <body></body> <script>console.log(screen.width);console.log(screen.height);console.log(screen…

在linux上安装jdk(转载)

软件环境&#xff1a; 虚拟机&#xff1a;VMware Workstation 10 操作系统&#xff1a;Ubuntu-12.04-desktop-amd64 JAVA版本&#xff1a;jdk-7u55-linux-x64 软件下载地址&#xff1a; JDK&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/index.html &a…