一、无参装饰器

1 开放封闭原则
软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的
也就是说我们必须找到一种解决方案:
能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能 总结,
原则如下:
1、不修改源代码
2、不修改调用方式
目的:
在遵循1和2原则的基础上扩展新功能 2、什么是装饰器?
器指的工具,装饰指的是为被装饰对象添加新功能 完整含义:
装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰器对象添加新功能 装饰器与被装饰的对象均可以是任意可调用的对象 装饰器=》函数
被装饰的对象=》函数 ''' import time #调用时间方法 def index():
start_time=time.time() #设定开始时间
time.sleep(3) #暂停3秒
print('welcome to index page')
stop_time=time.time()  #设定结束时间
print('run time is %s' %(stop_time-start_time)) #开始时间减结束时间,等于用的时间 index() #修订1:
import time def index():
time.sleep(3)
print('welcome to index page') def home(name):
time.sleep(5)
print('welcome %s to home page' %name) start_time=time.time()    #将时间操作单独拿出使用
index()
stop_time = time.time()
print('run time is %s' % (stop_time - start_time)) start_time=time.time()
home('egon')
stop_time = time.time()
print('run time is %s' % (stop_time - start_time)) #修订2:
import time def index():
time.sleep(3)
print('welcome to index page') def home(name):
time.sleep(5)
print('welcome %s to home page' %name) def wrapper(func): #func=index #把时间操作放到函数中
start_time=time.time()
func() #index()
stop_time = time.time()
print('run time is %s' % (stop_time - start_time)) wrapper(index) # 修改了原函数的调用方式 #修订3:
import time def index(): #原index函数
time.sleep(3)
print('welcome to index page') def outter(func): #func=最原始的index #闭合函数,外包
# func=最原始的index
def wrapper(): #嵌套定义的函数
start_time=time.time()
func()
stop_time=time.time()
print(stop_time-start_time)
return wrapper index=outter(index) # 新的index=wrapper #将返回值wrapper赋予index index() #wrapper() #等于weapper函数

二、无参装饰器升级版

import time

def index():
time.sleep(1)
print('welcome to index page')
return 122 def home(name):
time.sleep(2)
print('welcome %s to home page' %name) #==============装饰器
def timmer(func): #外包
#func=最原始的home
def wrapper(*args,**kwargs): #嵌套函数,赋予形参*args,**kwargs,用于解决调用函数自带参数问题
start_time=time.time()
res=func(*args,**kwargs) #调用最原始的home,将值赋予res留返回
stop_time=time.time()
print(stop_time-start_time)
return res #对应带返回值的函数处理
return wrapper index=timmer(index) # 新的index=wrapper
home=timmer(home) #新的home=wrapper
# ========================================== home(name='egon') #wrapper('egon')
index() #wrapper() #无参装饰器模板
def outer(func):
def inner(*args,**kwargs):
res=func(*args,**kwargs)
return res
return inner

三、装饰器语法

关键字@,@后面跟装饰器函数名,正下面为需要用到装饰器的函数,@必须单独一行

import time
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(stop_time-start_time)
return res
return wrapper @timmer #index=timmer(index)
def index():
time.sleep(1)
print('welcome to index page')
return 122 @timmer # home=timmer(home)
def home(name):
time.sleep(2)
print('welcome %s to home page' %name) # index()
home('egon')

四、叠加多个装饰器

import time
current_user={ #字典用于存用户名
'username':None,
# 'login_time':None
} def auth(func): #注册装饰器
# func=index
def wrapper(*args,**kwargs):
if current_user['username']:
print('已经登陆过了')
res=func(*args,**kwargs)
return res uname=input('用户名>>: ').strip()
pwd=input('密码>>: ').strip()
if uname == 'egon' and pwd == '123':
print('登陆成功')
current_user['username']=uname
res=func(*args,**kwargs)
return res
else:
print('用户名或密码错误')
return wrapper def timmer(func): #时间装饰器
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(stop_time-start_time)
return res
return wrapper @timmer # timmer 统计的是auth+index的执行时间
@auth
def index():
time.sleep(1)
print('welcome to index page')
return 122 index() 两种装饰器叠加使用(红字),timmer为下只统计index的运行时间,放上面统计的是auth+index的执行时间

五、有参数装饰器

import time
current_user={
'username':None,
# 'login_time':None
} def auth(engine): #再在外面定义一个有参函数用于传值,三层装饰器
# engine='file'
def auth2(func): #第二层包第一层
# func=index
def wrapper(*args,**kwargs): #第一层
if engine == 'file':
if current_user['username']:
print('已经登陆过了')
res=func(*args,**kwargs)
return res uname=input('用户名>>: ').strip()
pwd=input('密码>>: ').strip()
if uname == 'egon' and pwd == '123':
print('登陆成功')
current_user['username']=uname
res=func(*args,**kwargs)
return res
else:
print('用户名或密码错误')
elif engine == 'mysql':
print('基于MyQL的认证')
elif engine == 'ldap':
print('基于LDAP的认证')
return wrapper
return auth2 #返回值为auth2
#用法 @第三层函数名加参数,因为执行到这段代码会运行,返回值为auth2,也就等于执行的是@auth2,成功赋值index
@auth('ldap') #@auth2 #index=auth2(index) #index=wrapper
def index():
time.sleep(1)
print('welcome to index page')
return 122 index() # wrapper()

Python之旅.第三章.函数3.29的更多相关文章

  1. Python之旅.第三章.函数4.01/4.02

    一.三元表达式 #普通的判断大小函数def max2(x,y): if x > y: return x else: return yres=max2(10,11)print(res)x=12y= ...

  2. Python之旅.第三章.函数3.30

    一.迭代器 1.什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来2.要想了解迭代器到底是什么?必须先了解一个概念,即什么是可迭代的对象?可迭代的对象:在python中,但凡内置 ...

  3. Python之旅.第三章.函数3.28

    一.命名关键字参数: 什么是命名关键字参数?格式:在*后面参数都是命名关键字参数特点:1 必须被传值1 约束函数的调用者必须按照key=value的形式传值2 约束函数的调用者必须用我们指定的key名 ...

  4. Python之旅.第三章.函数3.27

    一.形参与实参 1.形参与实参是什么? 形参(形式参数):指的是 在定义函数时,括号内定义的参数,形参其实就变量名 实参(实际参数),指的是 在调用函数时,括号内传入的值,实参其实就变量的值 x,y是 ...

  5. Python之旅.第三章.函数3.26

    一.函数: 1.为什么要有函数?什么是函数? 1.组织结构不清晰,可读性差 2.代码冗余 3.管理维护的难度极大,扩展性 具备某一个功能的工具就是程序的中函数 事先准备工具的过程---->函数的 ...

  6. python学习心得第三章

    python学习心得第三章 1.三元运算 变量=值1 if 条件 else 值2 由图如果条件成立则赋值1给变量,如果条件不成立则赋值2给变量. 2.数据类型 集合:set() class set(o ...

  7. python学习笔记——第三章 串

    第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...

  8. 《零压力学Python》 之 第三章知识点归纳

    第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...

  9. 跟着高淇学Python——第一到第三章总结

    2019/10/26 第一章:Python介绍 Python是一种解释型,面向对象的语言.特点是: 可读性强 简洁,简洁 面向对象 免费开源 可移植性和跨平台性 丰富的库 可扩展性 应用范围:1.人工 ...

随机推荐

  1. sql性能优化之多表联查

    先贴上我优化后的核心代码: select * into #result from ( select p.AchivementCount,isnull(a.ByAttentionCount,0) ByA ...

  2. 进程互斥 Peterson算法

    转自http://blog.csdn.net/l294265421/article/details/46674847 假设有两个进程需要互斥的访问某一个临界区. Peterson算法的形式如下: en ...

  3. 漫谈PID——实现与调参

    闲话: 作为一个控制专业的学生,说起PID,真是让我又爱又恨.甚至有时候会觉得我可能这辈子都学不会pid了,但是经过一段时间的反复琢磨,pid也不是很复杂.所以在看懂pid的基础上,写下这篇文章,方便 ...

  4. ADS协议变量配置界面

    ADS协议是倍福产品的通信协议,在双击ADS协议图标后打开如下图的配置窗口. 变量配置表中各列的含义: 报警类型: 脚本: 当设置了报类型时,在运行时如果变量值引发报警时将执行一次脚本.例如 大于报警 ...

  5. Cucumber 相关资源

    Cucumber support: https://cucumber.io/support yan1234abcd的专栏:http://blog.csdn.net/yan1234abcd/articl ...

  6. [ETL] Flume 理论与demo(Taildir Source & Hdfs Sink)

    一.Flume简介 1. Flume概述 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据: ...

  7. 20165226 预备作业3 Linux安装及学习

    20165226 预备作业3 Linux安装及学习 Linux安装 一.下载安装VirtualBox 1.首先在官网下载,点开基于VirtualBox虚拟机安装Ubuntu图文教程 找到版本进行下载安 ...

  8. 列表生成式、生成器&迭代器

    一.列表生成式 先有列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,怎么实现? 方法一: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, ...

  9. webpack安装入门

    这两天心血来潮,突然想研究下webpack,花了一天时间,看网上有很多教程,不过发现安装的都是比较老的版本.后来发现还是我太年轻了,找技术播客还不如找官方网站.下面是一个webpack的官方网站,里面 ...

  10. 【网络】 数据链路层&物理层笔记

    数据链路层 简称链路层,功能在于将数据包封装成帧,控制帧对介质的访问.链路层连接了物理介质和其之上抽象层,可以使上层不用关心用什么方法在什么介质中传输信息. 在帧被传输时经过的每一跳,每个中间设备(通 ...