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> >> ...
随机推荐
- phpstorm激活码生成器地址
http://idea.qinxi1992.cn/ 写在windows/system32/drivers/etc/hosts里 0.0.0.0 account.jetbrains.com 激活码位置: ...
- HashMap源码解析(JDK1.8)
package java.util; import sun.misc.SharedSecrets; import java.io.IOException; import java.io.Invalid ...
- cmd 命令大全
1.windows 系统定时关机 定时关机:shutdown -s -t 300 at 18:30 shutdown -s 取消定时:shutdown -a 注意:300为秒数,在windows co ...
- 【Python】 docker-py 用Python调用Docker接口
[docker-py] 官方文档:[https://docker-py.readthedocs.io/en/stable/images.html] 众所周知,Docker向外界提供了一个API来管理其 ...
- Algorithm --> Dijkstra和Floyd最短路径算法
Dijkstra算法 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必 ...
- linux小白成长之路3————更新yum源
[内容指引] 进入目录:cd 查看目录下的内容:ls 重命名备份:mv 从网络下载:wget yum更新:yum update 第一次运行yum安装软件前,建议更新yum. 1.进入yum源目录 命令 ...
- java中的IO 的示例
字符流 package jd_1; import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileNot ...
- 如何打包静态库.a文件 iOS
代码调试好了开始打包成sdk,下面是将要打包的FRSDK代码(FRSDK.h暴露在外面有别人调用) 1.创建新工程(Xcode File-New-Project) 2.把下面的红色框的东西移除 3.将 ...
- Django学习(六)---博客文章页面的超链接设置
Django中的超链接 超链接的目标地址 href后面是目标地址 template中可以用 {% url 'app_name : url_name' param %} app_name:应用命名 ...
- C语言博客作业——函数
一.PTA实验作业 题目1:6-6 使用函数输出水仙花数 1.本题PTA提交列表 2. 设计思路 int narcissistic( int number ) //函数定义 1.定义整数型变量a.i分 ...