python学习日记(函数--装饰器)
楔子
前提,我有一段代码(一个函数)。
- import time
- def run_time():
- time.sleep(0.1)
- print('我曾踏足山巅')
需求1:现在,我想计算这段代码的运行时间。
我可以这样做:
- import time
- def run_time():
- start_time = time.time()
- time.sleep(0.1)
- print('我曾踏足山巅')
- end_time = time.time()
- run_t = end_time - start_time
- print('运行时间为:',run_t)
- run_time()
此时,需求是可以实现的。
需求2:不想如此麻烦
如果有很多个类似的函数需要计算运行时间,那这种方法就会显得特别繁琐。
我们可以不修改源代码,再定义一个计算时间的函数,将需要被计算时间的函数名作为参数传进去,
直接调用函数进行计算运行时间,就不需要每个函数里面都加入相同代码了。
下面进行升级:
- import time
- def run_time():
- time.sleep(0.1)
- print('我曾踏足山巅')
- def run_time1():
- time.sleep(1)
- print('也曾堕入低谷')
- def calculation(f):
- start_time = time.time()
- f()
- end_time = time.time()
- run_t = end_time - start_time
- print('运行时间为:', run_t)
- #直接调用函数进行计算
- calculation(run_time)
- calculation(run_time1)
需求3:我还想要不修改调用方式直接实现时间的计算。
即还是直接调用原函数,但是能同时实现原功能以及时间计算的功能。
由此,我们引入装饰器函数的概念。
python装饰器
装饰器的定义
python装饰器就是用来拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数。
使用python的好处就是不用更改原函数代码的前提下给函数增加新的功能。
装饰器的特点
不修改被装饰函数的调用方式,不修改被装饰函数的源代码。
实例:实现
备注:语法糖
- import time
- def run_time(f): #装饰器函数
- def inner():
- start_time = time.time()
- f()
- end_time = time.time()
- run_t = end_time - start_time
- print('运行时间为:', run_t)
- return inner
- # func = run_time(func)#不修改函数调用方式,添加新功能
- @run_time#语法糖,代替赋值调用,等价于上一行代码
- def func():
- time.sleep(0.1)
- print('hello world')
- func()
可以看出,在不改变原函数调用方式的情况下,也实现了运行时间的计算。
原函数的源码没有改变,调用方式没有改变,并且追加了新的运行时间计算功能。
装饰器的返回值
如果被装饰的参数有返回值。
- import time
- #装饰器必定要是一个闭包函数
- def run_time(f):
- def inner():
- start = time.time()
- func_retrun = f() # func_return = func() 变量接收被装饰函数的返回值
- end = time.time()
- print('被装饰函数运行时间为:',end - start)
- return func_retrun
- return inner
- @run_time
- #被装饰函数
- def func():
- time.sleep(0.1)
- print('hello world')
- return '这是被装饰函数返回值'
- # func = run_time(func) #结果:func = inner
- s = func()
- print(s)
装饰器的参数
一、位置参数
- #带有参数的函数装饰器
- def wrapper(f):
- def inner(a):
- print('装饰器增加的额外内容:hello world')
- return f(a)#返回被装饰函数的返回值
- # f(a)
- return inner
- @wrapper
- def func(a):
- print('被装饰函数的参数输入:',a)
- return '被装饰函数的返回值:was a day'
- s = func('once before,a little ...')
- print(s)
二、默认参数
- #此装饰器 wrapper 实现增加时间戳功能
- import time
- def wrapper(f):
- def inner(a,b,c = 'default'):#在这里加默认参数,还有动态参数亦如是
- print(time.asctime())
- r = f(a,b,c)
- return r
- return inner
- @wrapper
- def func(a,b,c ):
- print(a,b,c)
- return '被修饰函数返回值'
- s = func(1,2)
- print(s)
三、动态参数
注:其实下例中的被装饰函数并没有用到参数。不过你可以根据需求自己来进行试验,不再赘述。
- # 此装饰器 wrapper 实现增加时间戳功能
- import time
- def wrapper(f):
- def inner(*args,**kwargs):
- print(time.asctime())
- r = f(*args,**kwargs)
- return r
- return inner
- @wrapper
- def func2():
- print(''' 三更灯火五更鸡,
- 正是男儿读书时。
- 黑发不知勤学早,
- 白首方恨读书迟。''')
- r1 = '''这首诗深入浅出,自然流畅,富含哲理。核心是“黑发早勤学,白首读书迟”。
- 从学习的时间这一角度立意,劝勉年轻人不要虚度光阴,要及早努力学习,免得将来后悔。'''
- return r1
- s = func2()
- print(s)
装饰器的功能和固定结构
装饰器的主要功能
在不改变函数调用的基础上在函数的前、后添加功能。
装饰器的固定结构
- def wrapper(f):#装饰器函数,f是被装饰函数
- def inner(*args,**kwargs):
- '''执行函数之前要做的'''
- r = f(*args,**kwargs)
- '''执行函数之后要做的'''
- return r#解释器原则,从上至下,返回值最后才进行输出
- return inner
- @wrapper #之后要使用装饰器函数的时候,直接调用就可以了
pass
python学习日记(函数--装饰器)的更多相关文章
- Python学习日记(九) 装饰器函数
1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...
- python学习日记(装饰器的补充)
如何返回被装饰函数的函数名及注释? 问题及实现 先看典型的装饰器: def wrapper(f):#装饰器函数,f是被装饰函数 def inner(*args,**kwargs): '''执行函数之前 ...
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- python 修改的函数装饰器
把好的代码记录下来 方便以后学习 修改的函数参数装饰器 from functools import wraps import time import logging def warn(timeout) ...
- Python学习笔记012——装饰器
1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...
- python学习笔记:装饰器2
python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...
- python二 总结--函数-- 装饰器
装饰器是什么? 有什么用? 为什么要用? 真的有用吗? 1.装饰器: 装饰器: 定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能. 原则:1.不能修改被装饰的函数的源代码 ...
- Python中的@函数装饰器到底是什么?
在解释@函数装饰器之前,先说一下,类中的类方法和静态方法. 在Python中完全支持定义类方法.静态方法.这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以). 区别在于:Pyt ...
- python语法基础-函数-装饰器-长期维护
######################################################### # 装饰器 # 装饰器非常重要,面试Python的公司必问, # 原则:开放封闭原则 ...
- python 进阶篇 函数装饰器和类装饰器
函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...
随机推荐
- 广州商学院16级软工一班&二班-第二次作业成绩
作业地址 https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2097 https://edu.cnblogs.com/campus/gzc ...
- pycharm导入自己写的.py文件时,模块下方出现红色波浪线解决
点击菜单栏的File,选择Setting, 然后,选择需要导入的.py文件“所在的目录",而非项目根目录,右键 之后再导入该.py文件就不会出现红色波浪线了.
- Day2 Numerical simulation of optical wave propagation之标量衍射理论基本原理(二)
2.麦克斯韦方程组的简单行波解 讨论通过线性.各向同性.均匀.无色散.无限电荷和电流的电介质材料的光波传输.在这种情况下,介质具有如下属性: (1)推导获得波动方程( 由麦克斯韦方程组导出的.描述电磁 ...
- 未能加载文件或程序集"Newtonsoft.Json, Version=4.5.0.0
这问题遇到好几次了,重新更改了引用都不好使,有的时候版本改成一致就好了,但是有的地方你不知道在哪里用了就不好排查,所性在config里面加个配置让程序运行的时候去处理得了~ 很实用,放在configu ...
- gnuplot画折线图
之前尝试用jfreechart画自定义横坐标的折线图或时序图,发现很复杂,后来改用gnuplot了. gnuplot在网上一搜就能找到下载地址. 安装完成后,主要是命令行形式的交互界面,至少比jfre ...
- 在Git中添加一个项目
首先保证Git服务器正确配置,管理员机器可正常连接并使用Git. 第一步:在服务器上新建一个项目仓库 切换到git用户: a@ubuntu:/home/git$ su - git $ cd /home ...
- 六、es6 map
一.map的特点 JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键.这给它的使用带来了很大的限制. 为了解决这个问题,ES6 提供了 ...
- php trait使用
trait类似于基类 同样的方法优先级为 本类>trait>基类 <?php /** * Created by PhpStorm. * User: mac * Date: 2019 ...
- Oracle 用户管理与权限分配
用户管理是系统管理员最基本的任务之一,用户想要连接数据库并且使用相应的系统资源就必须是系统的合法用户且具有对应的权限. 1 创建用户 default tablespace default_tables ...
- Day3-2 函数之递归
递归 定义:一个函数在 内部调用自己,就称为递归. # 如何让10不停的除以2,直到不能除为止. n = 10 while True: n = int(n /2) print(n) if n == 0 ...