day10.闭包函数与装饰器
一.闭包函数
1.闭函数:被封闭起来的函数==>定义在函数内部的函数,特点是只能在函数内调用
2.包函数:该函数引用了一个名字,该名字来自于E这一层
总结:闭包函数指的是定义在函数内部的函数引用了一个来自于外层函数作用域中的名字
#例如wrapper函数
# def outter():
# x = 100
# def wrapper():
# print(x)
3.闭包函数升级:结合函数对象
# def outter():
# x = 100
# def wrapper():
# print(x)
# return wrapper # 千万不要加括号
#
# f = outter()
#
# print(f)
#
# def foo():
# x = 666
# f()
#
# foo()
4.为函数体传参的两种解决方案
方案一:直接以参数的形式传入
# def wrapper(x):
# print(x)
#
# wrapper(100)
方案二:闭包函数方式
# def outter(x):
# # x = 100
# def wrapper():
# print(x)
# return wrapper # 千万不要加括号
#
# f = outter(100)
# f()
二.装饰器
1.什么是装饰器
’装饰’代指为被装饰对象添加新的功能
’器’代指器具/工具
但实现装饰器必须遵循的原则是:开放封闭原则
开放指的是对拓展新功能是开放的,封闭指的则是对修改源代码以及调用方式是封闭的
#综上装饰器指的是我们要创建一个工具,该工具可以在遵循原则1和2的前提下还能为被装饰对象添加新功能
原则1、不修改被装饰对象源代码
原则2、不修改被装饰对象调用方式
2.为什么要用装饰器
软件包含的所有功能的源代码以及调用方式,都应该避免修改,否则一旦改错,则极有可能产生连锁反应,最终导致程序崩溃,而对于上线后的软件,新需求或者变化又层出不穷,我们必须为程序提供扩展的可能性,这就用到了装饰器。
3.用法
**装饰器的推导**
# 被装饰者:给被装饰者添加新功能
# import time
#
# def index():
# print('from index')
# time.sleep(3)
#
# index() # 方案一:改变被装饰者的源代码
# import time
#
# def index():
# start = time.time()
# print('from index')
# time.sleep(1)
# end = time.time()
# print('run time is %s' %(end - start))
#
# index() # # 方案二:装饰器的功能需要重复编写,代码冗余
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
#
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
# # # 方案三:解决方案二的代码冗余问题,但是存在问题-》装饰器的功能写死了,只能装饰index函数
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# def wrapper():
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
#
# wrapper()
# wrapper() # # 方案四:装饰器的功能写活
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# def outter(func):
# # func = index
# def wrapper():
# start = time.time()
# func()
# end = time.time()
# print('run time is %s' %(end - start))
# return wrapper
#
# index = outter(index) # index = wrapper的内存地址
# # print(index)
# index() # 方案五:装饰器的功能写活
import time def index():
print('from index')
time.sleep(1) def home(name):
print('welcome %s to home page' % name)
time.sleep(0.5)
return 123 def outter(func):
# func = 最原始那个home的内存地址
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs) # 最原始那个home的内存地址()
end = time.time()
print('run time is %s' % (end - start))
return res
return wrapper home = outter(home) # home = wrapper的内存地址
index = outter(index) # home = wrapper的内存地址 res = home('egon')
print(res) # res = index()
# print(res)
**装饰器语法糖**(简化)
import time def outter(func):
# func = 最原始那个home的内存地址
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs) # 最原始那个home的内存地址()
end = time.time()
print('run time is %s' % (end - start))
return res return wrapper @outter # index = outter(index)
def index():
print('from index')
time.sleep(1) @outter # home = outter(home)
def home(name):
print('welcome %s to home page' % name)
time.sleep(0.5)
return 123 res = home('lzl')
print(res)
**多个装饰器叠加**
# 装饰器模板
# def deco(func):
# def wrapper(*args,**kwargs):
# res = func(*args,**kwargs)
# return res
# return wrapper # 统计时间的装饰器
# import time
#
# def timmer(func):
# def wrapper(*args,**kwargs):
# start = time.time()
# res = func(*args,**kwargs)
# stop = time.time()
# print(stop - start)
# return res
# return wrapper # 认证功能装饰器
# def auth(func):
# def wrapper(*args,**kwargs):
# inp_user = input('Username: ').strip()
# inp_pwd = input('Password: ').strip()
# if inp_user == 'egon' and inp_pwd == '123':
# res = func(*args,**kwargs)
# return res
# else:
# print('登录失败')
# return wrapper
#
# @auth # index = auth(index)
# def index():
# print('from index')
#
# index() """
def deco1(func1): # func1 = wrapper2的内存地址
def wrapper1(*args,**kwargs):
print('===>wrapper1')
res1 = func1(*args,**kwargs)
print('=====>end wrapper1')
return res1
return wrapper1 def deco2(func2): # func2 = wrapper3的内存地址
def wrapper2(*args,**kwargs):
print('===>wrapper2')
res2 = func2(*args,**kwargs)
print('=====>end wrapper2')
return res2
return wrapper2 def deco3(func3): # func3 = 最原始那个index的内存地址
def wrapper3(*args,**kwargs):
print('===>wrapper3')
res3 = func3(*args,**kwargs)
print('=====>end wrapper3')
return res3
return wrapper3 # index = wrapper1的内存地址
@deco1 # deco1(wrapper2的内存地址) ---> wrapper1的内存地址
@deco2 # deco2(wrapper3的内存地址) ---> wrapper2的内存地址
@deco3 # deco3(最原始那个index的内存地址) ---> wrapper3的内存地址
def index():
print('=======>index') index()
""" # print(index) import time def timmer(func):
def wrapper1(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
stop = time.time()
print(stop - start)
return res
return wrapper1 def auth(func):
def wrapper2(*args,**kwargs):
inp_user = input('Username: ').strip()
inp_pwd = input('Password: ').strip()
if inp_user == 'egon' and inp_pwd == '123':
res = func(*args,**kwargs)
return res
else:
print('登录失败')
return wrapper2 @auth
@timmer
def index():
print('====>index')
time.sleep(3)
index()
有参装饰器:
def outter2(mode,yyy):
# mode = 'mysql'
def outter(func): # func = index
def wrapper(*args ,**kwargs):
print(yyy)
inp_user = input('Username: ').strip()
inp_pwd = input('Password: ').strip()
if mode == 'file':
if inp_user == "egon" and inp_pwd == "123":
res = func(*args ,**kwargs)
return res
else:
print('login failed')
elif mode == 'mysql':
print("基于mysql数据库的认证")
elif mode == 'ldap':
print("基于ldap数据库的认证")
else:
print('未知的认证来源')
return wrapper
return outter @outter2('mysql',111) # @outter # index = outter(index) # index = wrapper
def index():
print('from index') @outter2('ldap',222)
def home(name):
print('hello %s' %name)
###functools模块下提供一个装饰器wraps专门用来保留原函数属性####
4.总结
1、无参装饰器模板
# def outter(func):
# def wrapper(*args,**kwargs):
# res = func(*args,**kwargs)
# return res
# return wrapper
#
# @outter
# def index():
# pass
2、有参装饰器模板
def outter2(xxx):
def outter(func):
def wrapper(*args,**kwargs):
xxx
res = func(*args,**kwargs)
return res
return wrapper
return outter @outter2(xxx=111)
def index():
pass
day10.闭包函数与装饰器的更多相关文章
- day11 闭包函数和装饰器
1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...
- python基础-闭包函数和装饰器
闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...
- Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器
目录 一 函数对象 二 函数的嵌套 三 名称空间和作用域 四 闭合函数 五 装饰器 一.函数对象 1.函数是第一类对象 #第一类对象的特性:# 可以被引用 # 可以当做参数传递 # 返回值是函数 # ...
- 【Python3的命名空间与作用域,闭包函数,装饰器】
一.命名空间与作用域 命名空间是名字和对象的映射,就像是字典,key是变量名,value是变量的值 1.命名空间的定义 name='egon' #定义变量 def func(): #定义函数 pass ...
- day11_7.11 闭包函数与装饰器
补充: callable 代表可调用的,加括号可以执行.(函数或者类) import this 查看python之禅 一.闭包函数 所谓闭包函数,就是定义在函数内部的函数,也就是函数定义的嵌套.而在 ...
- CSIC_716_20191112【闭包函数和装饰器】
闭包函数 什么是闭包函数:闭包函数是函数嵌套.函数对象.名称空间和作用域的集合体. 闭包函数必须在函数内部定义,闭包函数可以引用外层函数的名字. # _*_ coding: gbk _*_ # @Au ...
- Python--day13(函数嵌套定义,global、nonlocal、闭包函数、装饰器)
今日主要内容 1. 函数的嵌套定义 2. global.nonlocal关键字 3. 闭包及闭包的应用场景 4. 装饰器 1. 函数的嵌套定义 概念:在一个函数的内部定义另一个函数 为什么要有 ...
- python---基础知识回顾(二)(闭包函数和装饰器)
一.闭包函数: 闭包函数: 1.在一个外函数中定义了一个内函数 2.内函数里运用了外函数的临时变量,而不是全局变量 3.并且外函数的返回值是内函数的引用.(函数名,内存块地址,函数名指针..) 正确形 ...
- Python之闭包函数、装饰器
1.闭包函数 #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关 # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1(): # x=1 # def inner(): ...
随机推荐
- vue学习遇到的问题
1.vue脚手架的安装,解决链接:https://www.cnblogs.com/qcq0703/p/14439467.html2.2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在 ...
- 微信小程序:app.json中通过使用扩展库userExtendedLib的方式,引入并使用weui
微信小程序 PK APP: 1.微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾:而推⼴app的成本太⾼. 2.微信小程序也可以跨平台(Android和IOS). 一.project. ...
- MySQL之九---分布式架构(Mycat/DBLE)
MyCAT基础架构图 双主双从结构 MyCAT基础架构准备 准备环境 环境准备: 两台虚拟机 db01 db02 每台创建四个mysql实例:3307 3308 3309 3310 删除历史环境 p ...
- HDOJ-6645(简单题+贪心+树)
Stay Real HDOJ-6645 由小根堆的性质可以知道,当前最大的值就在叶节点上面,所以只需要排序后依次取就可以了. #include<iostream> #include< ...
- Java 语言基础 02
语言基础·二级 顺序结构语句 * A:什么是流程控制语句 * 流程控制语句:可以控制程序的执行流程. * B:流程控制语句的分类 * 顺序结构 * 选择结构 * 循环结构 * ...
- 实话实说:只会.NET,会让我们一直处于鄙视链、食物链的下游
金三银四,是个躁动的季节. 结合最近的面试,谈一谈一个老牌开发人员的面试感悟. 大家都知道我的主力技术栈是 .NET + Devops + 弱前端 (当前技术认知,不排除以后变化). 面试了大小厂,有 ...
- 【关系抽取-R-BERT】加载数据集
认识数据集 Component-Whole(e2,e1) The system as described above has its greatest application in an arraye ...
- 轻量易用的微信Sdk发布——Magicodes.Wx.Sdk
概述 最简洁最易于使用的微信Sdk,包括公众号Sdk.小程序Sdk.企业微信Sdk等,以及Abp VNext集成. GitHub地址:https://github.com/xin-lai/Magico ...
- c++ 反汇编 if
1.debug if: 10: if (argc == 0) 0010711E 83 7D 08 00 cmp dword ptr [argc],0 00107122 75 11 jne If+35h ...
- io流(文件字符流(FileReader,FileWriter文件的复制))
文件字符流(FileReader,FileWriter文件的复制) 文件的复制 效率低的方法 注意:字符流需要刷新操作,字节流不需要,只有刷新后才可以将程序中的内容导入到目标文件中 package c ...