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> >> ...
随机推荐
- selenium webdriver 使用Chrome 浏览器
首先需要有ChromeDriver驱动来协助.ChromeDriver是实现WebDriver有线协议的一个单独的服务.ChromeDriver通过chrome的自动代理框架控制浏览器,ChromeD ...
- 写了个批量查询qs的软件
因为需要,自己写了个批量查询qs的小软件.从网站中抓出需要的数据,格式化显示: 对字符串进行检测处理,先用Replace函数去掉字符串的空格,再用正则表达式匹配,返回匹配的字符串,如果没有匹配,则返回 ...
- 快速搭建CentOS+ASP.NET Core环境支持WebSocket
环境:CentOS 7.x,.net core 2 以下.net core 2安装操作为官方方法.如果你使用Docker,那么更简单了,只需要docker pull microsoft/dotnet就 ...
- vue的图片上传
转载 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- ASCII代码
ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧 ...
- 笔记:Spring Cloud Feign Hystrix 配置
在 Spring Cloud Feign 中,除了引入了用户客户端负载均衡的 Spring Cloud Ribbon 之外,还引入了服务保护与容错的工具 Hystrix,默认情况下,Spring Cl ...
- 笔记:Spring Boot 项目构建与解析
构建 Maven 项目 通过官方的 Spring Initializr 工具来产生基础项目,访问 http://start.spring.io/ ,如下图所示,该页面提供了以Maven构建Spring ...
- 笔记:Eclipse 安装 Hibernate Tools
在线安装,要求 Eclipse Neon 4.6 版本和Java 8,在 Help > Install New Software,在打开的窗体中的 Work with 中输入URL地址" ...
- PHP Session 常用的函数
我们在前面的文章里面讲到session的原理和最佳实践,感到意犹未尽.现在再来聊下PHP Session用到的几个相关的函数. session_start() session_start() 会创建新 ...
- SQL 数据库连续插入大批量数据时超时
经常会处理大批量千万级的数据,一直以来都没问题.最近在处理时确出来了经常超时,程序跑一段时间就得停下来重启服务器,根据几次的调整发现了问题的所在,产生这类问题主要是以下几点所导致: 1.数据 ...