【python3】 函数 装饰器
第一步 : 了解装饰器
装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象。
举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就不是一件真正的短袖了。
于是有了长袖的诞生,将长袖套在短袖外面,既可挡风又可御寒,妈妈再也不用担心我感冒了。短袖是短袖,长袖是长袖,相互独立。
装饰器就像我们的长袖,在不影响短袖改造的情况下,达到了挡风御寒的效果。
装饰器的应用场景:插入日志、性能测试、事务处理、缓存等。
第二步 : 定义一个基础函数(短袖)
def short_T():
## 定义一个基础函数
print("穿了一件短袖") short_T()
第三步:写一个测试函数执行时间的函数(长袖)
import time def long_T(func):
## 定义一个测试函数执行时间的函数(装饰函数)
def inner():
start_time = time.time()
short_T
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner def short_T():
print("穿了一件短袖") short_T = long_T(short_T()) ## =====>装饰器实质:装饰函数的参数是被装饰函数的对象()
short_T()
执行顺序:
1、python解释器开始执行后,引入time模块;
2、先读函数long_T,再读函数short_T(将函数名放在内存,但不执行);
3、执行调用者等号右边long_T(short_T),执行long_T函数,并将参数short_T传入函数;
4、读函数inner,将inner函数的返回值inner赋值给调用者short_T(则short = inner),执行inner()函数(则short_T = inner());
5、计算开始时间,(传入参数为:short_T,则func() = short_T()),执行short_T函数,打印“穿了一件函数”;
6、计算函数结束与开始时间的差值,并打印差值,函数执行完毕。
第四步 : 使用语法糖(@)装饰函数(换一件好看的长袖)
'''
使用语法糖(@被装饰函数)来代替 short_T = long_T(short_T()
''' import time def long_T(func):
## 定义一个测试函数执行时间的函数
def inner():
start_time = time.time()
func()
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner @long_T
def short_T():
## 定义一个基础函数
print("穿了一件短袖") short_T()
第五步 : 装饰器--hold住所有参数的装饰器
import time def long_T(func):
## 定义一个测试函数执行时间的函数
def inner(*args,**kwargs): ## 添加万能参数
start_time = time.time()
func(*args,**kwargs) ## 添加万能参数
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner @long_T
def short_T(a,b): ## 无论传多少参数,装饰器都能接收
## 定义一个基础函数
print("%s和%s穿了一件短袖"%(a,b)) short_T("小白","小黑")
第六步 : 装饰器--有返回值的装饰器
import time def long_T(func):
## 定义一个测试函数执行时间的函数
def inner(*args,**kwargs):
start_time = time.time()
ret = func(*args,**kwargs) ## 接收返回的值
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return ret ## 返回接收的值给接收者
return inner @long_T
def short_T(a,b):
## 定义一个基础函数
return("%s和%s穿了一件短袖"%(a,b)) print(short_T("小白","小黑")) ## 打印返回的值
装饰器模板:
def wrapper(func):
def inner(*args,**kwargs):
## 执行函数前操作
ret = func(*args,**kwargs)
## 执行函数后操作
return ret
return inner
开放封闭原则
1、对扩展是开放的:任何一个程序,做到完美,总是经过不断的迭代来升级更新,所有我们必须允许代码扩展,添加新功能;
2、对修改的封闭的:其一,开发写的函数,有交付给其他人去使用,如果进行修改,很可能影响其他正在使用函数的用户;
其二,在原有功能上修改函数,很有可能牵一发而动全身,引发其他部分的bug。
装饰器遵循了开放封闭原则
1) 获取装饰器函数的函数名和注释信息:
def wrapper(func):
def inner(*args,**kwargs):
'''执行函数前操作'''
ret = func(*args,**kwargs)
'''执行函数后操作'''
return ret
return inner @wrapper
def f1():
''' 注释信息 '''
print(f1.__name__) ## 获取函数名
print(f1.__doc__) ## 获取函数注释信息 f1() # ==== inner() 运行结果: inner
执行函数前操作
2)获取被装饰器函数的函数名和注释信息:
from functools import wraps ## 引入模块
def wrapper(func):
@wraps(func) ## 放在最内层函数正上方
def inner(*args,**kwargs):
'''执行前操作'''
ret = func(*args,**kwargs)
'''执行后操作'''
return ret
return inner @wrapper
def name():
'''注释信息'''
print(name.__name__)
print(name.__doc__)
name() 运行结果:
name
注释信息
【python3】 函数 装饰器的更多相关文章
- python3 使用装饰器,及函数作为参数
#装饰import typesdef shucai(n): print('蔬菜价格7') if type(n)==types.FunctionType: return n()+7 return n+7 ...
- Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- (转)Python3.5——装饰器及应用详解
原文:https://blog.csdn.net/loveliuzz/article/details/77853346 Python3.5——装饰器及应用详解(下)----https://blog.c ...
- python3.7 装饰器
#!/usr/bin/env python __author__ = "lrtao2010" #python3.7 装饰器 #装饰器 ''' 定义:本质就是一个函数,作用是为其他函 ...
- Python函数装饰器高级用法
在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...
- Python高手之路【四】python函数装饰器
def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...
- Python: 无参数的函数装饰器
写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数.但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函 ...
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- python 函数 装饰器 内置函数
函数 装饰器 内置函数 一.命名空间和作用域 二.装饰器 1.无参数 2.函数有参数 3.函数动态参数 4.装饰器参数 三.内置函数 salaries={ 'egon':3000, 'alex':10 ...
随机推荐
- 给opencart产品页添加额外信息
有时我们在开发opencart时需要给产品页添加一些额外的信息,第一种聪明的方法可以修改并调用已有字段,详细可以参考opencart3产品页调用upc/数量等信息:如果您的开发能力不错的话可以用第二种 ...
- 解决git pull/push每次都需要输入密码问题 和 HttpRequestException encountered
如果我们git clone的下载代码的时候是连接的https://而不是git@git (ssh)的形式,当我们操作git pull/push到远程的时候,总是提示我们输入账号和密码才能操作成功,频繁 ...
- emqx源码编译
1 下载 github上下载 2 找台虚拟机,安装编译所需的环境,erlang make等 3 执行make命令 重点说一下第3步: 主要是make命令报错 解释:执行make命令后,依赖 ...
- Oracle SQL 部分特殊字符转义及escape的用法
在处理sql时,遇到insert 或update 的参数中含有特殊字符“&”,下划线“_”, 单引号" ' "等时,要做转义处理. 例:插入特殊字元'&' upda ...
- HDFS组件性能调优:数据平衡
生产系统中什么情况下会添加一个节点呢? 1 增加存储能力 disk 2 增加计算能力 cpu mem 如果增加是的是存储能力,说明存储已接近饱和或者说过段时间就会没有剩余的空间给作业来用.新加的节点存 ...
- Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法2
这里使用一种更高效地从深度纹理中重建世界坐标的方法. 首先计算摄像机的视锥体的四条射线向量进行线性插值,插值后的值便是该像素在世界空间坐标下到摄像机的方向. 然后通过与深度值相乘即可得到摄像机位置到该 ...
- TCP三次握手及TCP连接状态 TCP报文首部格式
建立TCP连接时的TCP三次握手和断开TCP连接时的4次挥手整体过程如下图: 开个玩笑 ACK: TCP协议规定,只有ACK=1时有效,连接建立后所有发送的报文ACK必须为1 SYN(SYNchron ...
- vue.js国际化vue-i18n插件的使用问题,在模版文本、组件方法、jsf方法里的使用
vue.js国际化vue-i18n插件的使用问题,在模版文本.组件方法.jsf方法里的使用 1.在文本里使用{{$t("xxx")}} <span>{{$t(" ...
- Node.js基础学习四之注册功能
前言:在Node.js学习(二)和(三)中介绍了如何在Node.js 中获取登录的用户名和密码与数据库进行验证并返回数据给客户端 需求:实现注册功能 为了区分登录和注册是两个不同的请求,在端口后面加上 ...
- Yii2 mysql查询 int自动变string解决办法
原因是PDO以string查询数据导致. 这个与YII没关系,是PDO的默认处理,解决方法只需在配置中的db配置中加上attributes的相关配置就行了,如下: 'components' => ...