当前位置:网站首页>闭包和装饰器
闭包和装饰器
2022-07-30 13:58:00 【笑 瘾】
一、python闭包
1、生命周期
def outer():
a = 10
print(f"test {a}")
outer()
2、闭包要满足的条件
2.1、必须要有内嵌函数
2.2、内涵数必须要引用外函数的变量
2.3、外函数必须返回内函数
示例:
def outer(x):
a = 300
def inner():
print(x+a)
return inner
d = outer(100)
d()
print(dir(d))
#形成闭包之后,闭包函数就会得到一个非空的__closure__属性
print(outer.__closure__,d.__closure__)
3、用闭包实例化的对象
.虽然代码都一样,但是创建的对象是不一样的,每次调用外函数都会重新执行,创建一个新的tmp_list和inner
def outer():
tmp_list = []
def inner(name):
tmp_list.append(name)
print(tmp_list)
return inner
d1 = outer()
d1("d1")
d1('d1')
d2 = outer()
d2('d2')
d2("d2")
二、装饰器
1、装饰器的介绍
1.是一种程序设计模式,不改变函数或类的源代码基础上,添加额外功能
2.装饰器的本质就是闭包函数,它需要把一个callable(函数,类)对象作为参数传递进来
2、引出装饰器
#为了引出装饰器
import time
#时间戳:
从1970到现在所经历的秒数
def func1():
time.sleep(2)
print("func1.........")
def func2():
time.sleep(3)
print("func2.........")
start = time.time()
func1()
end = time.time()
print(f"func1执行花了{end - start }秒")
start = time.time()
func2()
end = time.time()
print(f"func2执行花了{end - start }秒")
3、统计运行时间的装饰器
#除了主功能之外还实现了其他功能
import time
def runtime(func):
def inner(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs) #让装饰器更加通用
end = time.time()
print(f"执行函数花了{end - start}秒")
return result
return inner
# @ 修饰符,去使用装饰器
@runtime #func1 = runtime(func1)
def func1():
time.sleep(2)
print("func1.........")
return "sanchuang"
@runtime
def func2(a,b):
time.sleep(3)
print("func2.........")
print(f"fun2...{a}{b}")
result = func1()
print(result)
func2(1,2)
4、用装饰器实现权限控制
import functools
import time
def deco(name):
def runtime(func):
#保留传递进来的函数的原数据,将它的原数据赋值给inner
@functools.wraps(func)
def inner(*args,**kwargs):
if name=="root":
print("欢迎")
print(f"func name is {func.__name__}")
result = func(*args,**kwargs)
return result
else:
return "没有权限"
return inner
return runtime
username = input("请输入你的用户名:")
@deco(name=username)
def add(a,b):
time.sleep(3)
return a+b
print(add(1,2))
三、装饰器的应用
1、可以应用多个装饰器去装饰函数,但是要注意装饰器的执行顺序
2、添加额外功能:计时、权限控制、日志记录等
3、案例:
import functools
import time
def runtime(func):
#保留传递进来的函数的原数据,将它的原数据赋值给inner
@functools.wraps(func)
def inner(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print(f"函数执行花了{end - start}s")
return result
return inner
def login_required(func):
username = input("请输入你的用户名:")
def inner(*args,**kwargs):
if username=='root':
print(f"欢迎执行{func.__name__}函数")
result = func(*args,**kwargs)
return result
else:
return "没有权限"
return inner
@login_required
@runtime
def add(a,b):
time.sleep(2)
return a+b
result = add(1,2)
print(result)
@login_required
@runtime
def add2(a,b):
time.sleep(3)
return a+b
result1 = add2(1,2)
print(result1)
四、带参数的装饰器
1、自身不传入参数的装饰器,使用两层函数定义
2、自身传入参数的装饰器,使用三层函数定义
import functools
import time
def deco(name):
def runtime(func):
#保留传递进来的函数的原数据,将它的原数据赋值给inner
@functools.wraps(func)
def inner(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print(f"函数执行花了{end - start}s")
print(f"name is {name}")
return result
return inner
return runtime
# runtime = deco(name = "sanle")
# func1 = runtime(func1)
@deco(name="sanle")
def func1():
time.sleep(3)
print("this is func1")
func1()
3、练习
装饰器带参数,来验证用户是否有权限运行函数
运行add函数,运行前要判断有没有权限
判断一:用户名和密码是否正确 ---用户名错误或密码错误
判断二:用户名是否为root,只有root用户有权限 ----输出用户没有权限
用户名和密码 通过带参传入
import functools
import time
def deco(name):
def runtime(func):
#保留传递进来的函数的原数据,将它的原数据赋值给inner
@functools.wraps(func)
def inner(*args,**kwargs):
if name=="root":
print("欢迎")
print(f"func name is {func.__name__}")
result = func(*args,**kwargs)
return result
else:
return "没有权限"
return inner
return runtime
username = input("请输入你的用户名:")
@deco(name=username)
def add(a,b):
time.sleep(3)
return a+b
print(add(1,2))
五、属性包装 装饰器----property
property:把方法当作属性来使用
class Person():
_age = 2
@property #property本身会创建另外两个装饰器,@age.setter @age.deleter
def age(self):
return self._age
@age.setter
def age(self,num):
if 0< num <120:
self._age = num
else:
raise ValueError("年龄不在范围")
p = Person()
print(p.age)
p.age = 110
print(p.age)
六、用类去实现装饰器
1、不带参数的装饰器用类实现
import time
class runtime:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
start = time.time()
result = self.func(*args,**kwargs)
end = time.time()
print(f"运行函数{self.func.__name__}花费了{end - start}秒")
return result
@runtime
def func1(a,b):
print("this is func1......")
time.sleep(2)
return a+b
print(func1(1,2))
2、带参数的装饰器用类实现
import time
class runtime:
def __init__(self,name):
self.name = name
def __call__(self,func):
def deco(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print(f"运行函数{func.__name__}花费了{end - start}秒")
return result
return deco
@runtime("name")
# a1 = runtime("name")
# func1 = a1(func1)
def func1():
time.sleep(2)
print("this is func1......")
func1()
七、装饰类
def outer(cls):
def inner(*args,**kwargs):
print(f"class name is:{cls.__name__}")
return cls(*args,**kwargs)
return inner
@outer # A = outer(A)
class A:
def __init__(self,name):
self.name = name
print(type(A))
m = A("sc")
print(m.name)
边栏推荐
- 机器学习在竞赛和工业界应用区别
- 容器排序案例
- Six-faced ant financial clothing, resisting the bombardment of the interviewer, came to interview for review
- 六面蚂蚁金服,抗住面试官的狂轰乱炸,前来面试复盘
- [VMware virtual machine installation mysql5.7 tutorial]
- OFDM Sixteen Lectures 3- OFDM Waveforms
- ESP32 反复重启问题 Arduino屏蔽断电探测器
- 【ROS进阶篇】第十一讲 基于Gazebo和Rviz的机器人联合仿真(运动控制与传感器)
- PyQt5快速开发与实战 9.1 使用PyInstaller打包项目生成exe文件
- 电池包托盘有进水风险,存在安全隐患,紧急召回52928辆唐DM
猜你喜欢

Container sorting case

Flask框架——Flask-Mail邮件

双碳目标下:农田温室气体排放模拟

MQTT网关读取西门子PLC数据传输到阿里云平台案例教程

LeetCode二叉树系列——102.二叉树的层序遍历

5. DOM

LeetCode二叉树系列——144.二叉树的最大深度

还在说软件测试没有中年危机?9年测试工程师惨遭淘汰

Still saying software testing doesn't have a midlife crisis?9 years of test engineers were eliminated

Understand Chisel language. 28. Chisel advanced finite state machine (2) - Mealy state machine and comparison with Moore state machine
随机推荐
5. DOM
网站添加能换装可互动的live 2d看板娘
接口自动化框架,lm-easytest内测版发布,赶紧用起来~
Chapter6 : Has Artificial Intelligence Impacted Drug Discovery?
Start learning C language
(一)Multisim安装与入门
A simple change for problem, knapsack problem sets of shell
[ARC092B] Two Sequences
OFDM 十六讲 3- OFDM Waveforms
[C# 循环跳转]-C# 中的 while/do-while/for/foreach 循环结构以及 break/continue 跳转语句
(论文翻译]未配对Image-To-Image翻译使用Cycle-Consistent敌对的网络
The main content of terrain analysis (the special effect level of the wandering earth)
Understand Chisel language. 28. Chisel advanced finite state machine (2) - Mealy state machine and comparison with Moore state machine
ccs软件的使用(靠谱挣钱的app软件)
JSON常用注解
Interface automation framework, lm-easytest beta version released, use it quickly~
Eight years of testing experience, why was the leader criticized: the test documents you wrote are not as good as those of fresh graduates
开源工具推荐:高性能计算辅助工具MegPeak
LeetCode二叉树系列——107.二叉树的层序遍历II
吃透Chisel语言.28.Chisel进阶之有限状态机(二)——Mealy状态机及与Moore状态机的对比