python基础篇_004_装饰器函数
python装饰器函数
1.装饰器函数引导
功能:计算函数执行时长
import time """
方式一:
函数首位添加时间,差值就是函数执行时间
缺点:每个函数都要加上,工作量大
"""
def f1():
start_time = time.time()
print("f1 excute")
end_time = time.time()
print(end_time-start_time) f1()
import time """
方式二:
调用函数前后
缺点:调用函数前后都要加,别人引用的也要加
""" def f1():
print("f1 excute") start_time = time.time()
f1()
end_time = time.time()
print(end_time - start_time)
import time """
方式三:
写个计算函数执行时间函数
缺点:改变了函数的调用方式
""" def f1():
print("f1 excute") def timer(func):
start_time = time.time()
func
end_time = time.time()
print(end_time - start_time) timer(f1())
想要不改变调用方式的前提下完成该功能
import time """
方式四:
缺点:还要复制操作
""" def f1():
print("f1 excute") def timer(func):
def inner():
start_time = time.time()
func
end_time = time.time()
print(end_time - start_time)
return inner f1 = timer(f1())
f1()
直接将赋值操作替换
import time def timer(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time) return inner @timer
def f1():
print("f1 excute") f1()
总结:
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
#带参数
import time
def timer(func):
def inner(a):
start = time.time()
func(a)
print(time.time() - start)
return inner @timer
def f1(a):
print(a) f1()
# 带返回值
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
print(time.time() - start)
return re
return inner @timer #==> func1 = timer(func1)
def func1(a,b):
print('in func1') @timer #==> func2 = timer(func2)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over' func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))
import time def timer(func):
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
print(a)
return 'f2 over' f1('x1', 'x2')
a = f2('a')
print(a)
# f1 excute ,a=x1,b=x2
# 0.0
# a
# 0.0
# f2 over
import time
# from functools import wraps def timer(func):
# @wraps(func) # 防止查看函数注释失效
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
"""f1函数注释"""
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
"""f2函数注释"""
print(a)
return 'f2 over' print(f1.__doc__) # 查看函数注释 None
print(f1.__name__) # 查看函数名称 inner
正常情况:
def demo():
"""函数注释"""
print("a") print(demo.__doc__) # 查看函数注释 函数注释
print(demo.__name__) # 查看函数名称 demo
为防止失效:
import time
from functools import wraps def timer(func):
@wraps(func) # 防止查看函数注释失效
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
"""f1函数注释"""
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
"""f2函数注释"""
print(a)
return 'f2 over' print(f1.__doc__) # 查看函数注释 f1函数注释
print(f1.__name__) # 查看函数名称 f1
2.开放封闭原则
1.对扩展是开放的
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。 2.对修改是封闭的
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。 装饰器完美的遵循了这个开放封闭原则
3.装饰器的主要功能和装饰器的固定结构
装饰器的主要功能:在不修改原函数的调用方式的基础上,在函数前后添加功能,实现功能扩展
from functools import wraps def demo(func):
@wraps(func) # 防止查看函数注释等方法失效
def inner(*args, **kwargs):
"""调用函数前要实现的功能"""
re = func(*args, **kwargs)
"""调用函数后要实现的功能"""
return re return inner
4.带参数的装饰器
使用参数控制装饰器的使用与否:在后面再嵌套一层
from functools import wraps def outer(flag):
def demo(func):
@wraps(func)
def inner(*args, **kwargs):
if flag: print("函数调用前")
re = func(*args, **kwargs)
if flag: print("函数调用后")
return re return inner return demo @outer(False)
def f1():
print("f1 execute") f1()
多个装饰器装饰同一个函数
from functools import wraps def timer1(func):
@wraps(func)
def inner(*args, **kwargs):
print('''timer1执行函数之前要做的''')
re = func(*args, **kwargs)
print('''timer1执行函数之后要做的''')
return re return inner def timer2(func):
@wraps(func)
def inner(*args, **kwargs):
print('''timer2执行函数之前要做的''')
re = func(*args, **kwargs)
print('''timer2执行函数之后要做的''')
return re return inner @timer1
@timer2
def func():
print(111) func()
# timer1执行函数之前要做的
# timer2执行函数之前要做的
#
# timer2执行函数之后要做的
# timer1执行函数之后要做的
python基础篇_004_装饰器函数的更多相关文章
- python 基础篇 12 装饰器进阶
本节主要内容:1. 通⽤装饰器回顾2. 函数的有⽤信息3. 带参数的装饰器4. 多个装饰器同时装饰⼀个函数 ⼀. 通⽤装饰器的回顾开闭原则: 对增加功能开放. 对修改代码封闭装饰器的作⽤: 在不改变原 ...
- 【笔记】Python基础五:装饰器
一,什么是装饰器 本质就是函数,功能是为其他函数添加附加功能 原则: 1,不修改被修饰函数的源代码 2,不修改被修饰函数的调用方式 例子: import time def timmer(func): ...
- python基础-内置装饰器classmethod和staticmethod
面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...
- Python学习日记(九) 装饰器函数
1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...
- python基础--闭包and装饰器
闭包函数:函数内部定义的函数:引用了外部变量但非全局变量 装饰器:有了闭包的概念再去理解装饰器就会相对容易一些.python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加 ...
- Python基础:13装饰器
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...
- python基础8(装饰器)
1.装饰器本质 装饰器的本质:一个闭包函数 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展 2.装饰器函数 假设要写一个输出函数执行时间的装饰器 def timer(func): ...
- python基础十之装饰器
1,装饰器的形成 编程原则:开放封闭原则. 开放:对扩展是开放的 封闭:对修改是封闭的 因为修改是封闭的,所以为了对函数进行功能的扩展,就使用装饰器! 2,装饰器的定义 # wrapper就是一个装饰 ...
- python基础5之装饰器
内容概要: 一.装饰器前期知识储备 1.python解释函数代码过程: python解释器从上往下顺序解释代码,碰到函数的定义代码块不会立即执行它,而是将其放在内存中,等到该函数被调用时,才执行其内部 ...
随机推荐
- 「线性基」学习笔记and乱口胡总结
还以为是什么非常高大上的东西花了1h不到就学好了 线性基 线性基可以在\(O(nlogx)\)的时间内计算出\(n\)个数的最大异或和(不需要相邻). 上述中\(x\)表示的最大的数. 如何实现 定义 ...
- vue---slot,slot-scoped,以及2.6版本之后插槽的用法
slot 插槽 ,是用在组件中,向组件分发内容.它的内容可以包含任何模板代码,包括HTML. vue 在 2.6.0 中,具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令).它取 ...
- Mybatis-PageHelper
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- JN_0001:在微信朋友圈分享时长大于10s的视频
1,先在聊天窗口里发送视频. 2,长按视频点击”收藏“. 3,进入微信收藏管理页面,播放视频. 4,点击右上角三点按钮,选择“转存为笔记”. 5,于是在收藏页面中会生成一个新的收藏笔记链接,打开链接再 ...
- 原生js封装cookie获取、设置及删除
使用cookie(key,value,options) 参数key,value,options(可选) function cookie(key,value,options){ if(typeof va ...
- .net 委托多线程 实时更新界面
Thread thread = new Thread(() => { button2.Invoke(new EventHandler(delegate { button2.Enabled = t ...
- luogu P5286 [HNOI2019]鱼
传送门 这题真的牛皮,还好考场没去刚( 这题口胡起来真的简单 首先枚举D点,然后对其他所有点按极角排序,同时记录到D的距离.然后按照极角序枚举A,那么鱼尾的两个点的极角范围就是A关于D对称的那个向量, ...
- webpack学习笔记——sourcemap(使用webpack打包的项目如何调试代码)
[webpack]devtool里的7种SourceMap模式是什么鬼? 里面详细介绍了7种模式的区别,和建议使用. webpack sourcemap 选项多种模式的一些解释 两篇文章大同小异,第一 ...
- 【译】索引进阶(六):SQL SERVER索引书签
[译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 在之前的章节,我们把索引看做一组有序条目的集合,每行数据对应一个索引条目.我们解释了很多关于索引逻辑方面的内容, ...
- C++设计模式——装饰模式
前言 在实际开发时,你有没有碰到过这种问题:开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作:而有一些非核心的操作,可能会使用,也可能不会使用:现在该怎么办呢? 将这 ...