Python入门之函数的装饰器
本章目录:
装饰器:
一、为什么要用装饰器
二、什么是装饰器
三、无参装饰器
四、装饰器语法糖
五、认证装饰器实现
六、叠加多个装饰器
七、带参装饰器
===========================================================
一、开放封闭原则
引子--为什么要用装饰器
软件一旦上线后,对修改源代码是封闭的,对功能扩展是开放的。
也就是说我们必须找到一种解决方案:
能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能
总结,原则如下:
1、不修改源代码
2、不修改调用方式
目的:
在原则1&2的基础上扩展新功能
二、什么是装饰器
装饰器(Decorator)是一种特殊的函数,用来给函数添上新功能的函数。
主要用于抽离大量函数中与函数本身无关的雷同代码并继续重用。
装饰器又可分为带参数和不带参数。
完整含义:
装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰器对象添加新功能
装饰器与被装饰对象均可以是任意可调用的对象
装饰器>>>函数
被装饰的对象>>>函数
三、装饰器实现之无参装饰器
装饰器的实现不能脱离,不能修改源代码,不能修改源调用方式的原则。下面我们将按照实现装饰器的思路,一步一步实现装饰器。
为下面的程序增加运行计时功能。
import time def index(): time.sleep()
print('This is Index Page!')
方案1:
import time def index():
start_time=time.time()
time.sleep(3)
print('welcome to index page')
stop_time=time.time()
print('run time is %s' %(stop_time-start_time)) index()
# 该方案虽然达到了计时功能,但是修改了源代码,违背了装饰器两大原则
方案2:
import time #引入时间包,方便调用time()方法 def index():
time.sleep(2)
print('This is Index Page.') start_time = time.time()
index()
stop_time = time.time()
print('The running time is %s' % (stop_time - start_time)
# 该方案虽然达到了计时功能,但是只是针对的增加代码,如果别的程序也要计时,还要重写一次,无法复用。
方案3:
import time def index():
time.sleep(2)
print('This is Index Page') def wrapper():
start_time = time.time()
index()
stop_time = time.time()
print('The running time is %s' % (stop_time - start_time))
# 该方案虽然达到了计时功能,但是要显示计时,还要去调用wrapper(),更改了原函数的调用方式
方案4:
import time def index():
time.sleep(2)
print('This is Index Page') def wrapper(func): #func = index start_time = time.time()
func(); #index
stop_time = time.time()
print('The running time is %s' % (stop_time, start_time)) wrapper(index)
# 该方案虽然达到了计时功能,但是要显示计时,不仅要调用wrapper(), 而且需要把原函数index作为参数导入,更改了原函数的调用方式
方案5(步入正轨之无参装饰器):
import time def index():
time.sleep()
print('This is Index Page') def outter(func): # func = 最初始的index
# func = index 巧用闭包,传递参数,
# 外部函数带的参数,就是准备给内部函数里用的,这里是闭包功能
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print('The running time is %s')
return wrapper index = outter(index) #初始index函数经过处理已经被变更为outter(index),被''装饰''了 index()
# 该方法能显示运行时长, 是把最初始的index函数通过闭包的特点,经过处理后重新把新的函数内存地址,赋值给了index,后面的index函数已经不是最初的index,它经过被''装饰''了
方案6(方案5的升级版):
1. 无参装饰器,引入带参函数的时候出现了错误。
# 不同于index()函数,这次我们引入一个新函数,带参数call_you(name)
import time def call_you(name):
time.sleep(2)
print('I call you %s' %name) def outter(func): def wrapper(name):
start_time = time.time()
res = func(name)
stop_time = time.time()
print('The running time is %s' % (stop_time - start_time)
return res return wrapper index = outter(index)
home = outter(home) #home带参,但是index不带参,这里运行会报错
方案7(解决方案6的问题):
# 运用可变长度参数处理这个问题
# 可变长度参数模版,注意参数是*args **kwargs
def outter(func):
def inner(*args, **kwargs):
res = func(*args, ** kwargs)
return res
return inner
import time def call_you(name):
time.sleep(2)
print('I call you %s' %name) def outter(func): def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
stop_time = time.time()
print('The running time is %s' %(stop_time - start_time))
return res
return wrapper
call_you = outter(call_you) call_you('Puppy')
四、装饰器语法糖
语法糖意指那些没有给计算机添加新功能,只是对人类来说更加“甜蜜”的语法,能够增加程序的可读性,减少代码出错的机会。
# 注意语法糖的放置位置,放在要用的函数的顶部,要用@开头

五、认证装饰器实现
1. 加入认证模块的简单实现:

2. 加入认证模块后登陆进行验证:

# 注意多个装饰器的顺序,按照顺序执行
1. 认证装饰器

2. 计时装饰器

3. 叠加多个装饰器(注意先后顺序)


Python入门之函数的装饰器的更多相关文章
- Python入门day04_函数与装饰器
一.函数入门 什么是函数: # 函数:函数是一系列代码的集,用来完成特定功能的代码块,类似于工具,可以重复不但的去使用 为什么要有函数: # 优点:# 1. 避免代码的冗余 # 2. 让程序代码结构更 ...
- Python基础之函数与装饰器
阅读目录 一.为什么要使用函数 二.函数的定义与调用 三.函数返回值 四.函数的参数 五.本章小结 六.装饰器 一.函数流程图: 函数名的命名规则: 1.函数名必须由字母下划线数字组成,不能是关键字和 ...
- python基础-闭包函数和装饰器
闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...
- Python高阶函数之 - 装饰器
高阶函数: 1. 函数名可以作为参数传入 2. 函数名可以作为返回值. python装饰器是用于拓展原来函数功能的一种函数 , 这个函数的特殊之处在于它的返回值也是一个函数 , 使用pyth ...
- Python全栈开发之路 【第五篇】:Python基础之函数进阶(装饰器、生成器&迭代器)
本节内容 一.名称空间 又名name space,就是存放名字的地方.举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方. 名称空间共3种,分别如下 ...
- Python之闭包函数、装饰器
1.闭包函数 #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关 # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1(): # x=1 # def inner(): ...
- Python学习之--函数/生成器/装饰器
Function,函数,主要是为了:1提高代码的复用程度,2将程序模块化. 定义函数 在Python中,使用def 用来定义函数,一般函数的定义如下: def name(arg1,arg2,....) ...
- python 高阶函数与装饰器
高阶函数定义1.函数接收的参数是一个函数名2.函数的返回值是一个函数名以上两者满足任意一个,就是高阶函数装饰器定义本质就是函数,功能是为其他函数添加新功能 装饰器的原则 1.不修改被装饰函数的源代码( ...
- python中高阶函数与装饰器(3)
>>> f = lambda x: x * x>>> f<function <lambda> at 0x101c6ef28> >> ...
随机推荐
- windows下安装Virtualenvwrapper
windows下安装Virtualenvwrapper 我们可以使用Virtualenvwrapper来方便地管理python虚拟环境,但是在windows上安装的时候.....直接 install ...
- ssh 提示Connection closed by * 的解决方案
使用ssh方式连接linux系统时,发现一直上报这个错误: Connection closed by 192.168.3.71 port 22 刚开始还以为是端口被防火墙禁止了呢,通过关闭和查看,并没 ...
- Mycat 配置说明(server.xml)
server.xml 几乎保存了所有mycat需要的系统配置信息,包括 mycat 用户管理.DML权限管理等,其在代码内直接的映射类为SystemConfig 类. user 标签 该标签主要用于定 ...
- 笔记:MyBatis XML配置-typeHandlers 默认类型处理器
类型处理器 Java 类型 JDBC 类型 BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN ByteTypeHandler j ...
- delete与delete[]的区别
一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论.做个备份,以免丢失. C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete ...
- Java中删除第一个集合中以某某开头的元素,删除第二个集合中以某某结尾的元素,并合并成一个集合
import java.util.ArrayList; import java.util.List; public class Test { public static void main(Strin ...
- docker部署PMA(LNMP架构)
上篇文章中已经部署好php环境,测试也已经OK centos 7 docker 启动了一个web服务 但是启动时 报 WARNING: IPv4 forwarding is disabled. Net ...
- [日常] AtCoder Beginner Contest 075 翻车实录
别问我为啥要写一篇ABC的游记... 周日打算CF开黑于是就打算先打打ABC找回手速... 进场秒掉 $A$ 和 $B$ , 小暴力一脸偷税 然后开 $C$ ...woc求桥? 怎么办啊我好像突然忘了 ...
- java中volatile
volatile用来修饰变量.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volat ...
- linux,windows,ubuntu下git安装与使用
ubuntu下git安装与使用:首先应该检查本地是否已经安装了git ,如果没有安装的话,在命令模式下输入 sudo apt-get install git 进行安装 输入git命令查看安装状态及常用 ...