9.23 闭包和装饰器
Posted lidandanaa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9.23 闭包和装饰器相关的知识,希望对你有一定的参考价值。
1.闭包函数:把闭包函数内部的变量和函数包起来,返回闭包函数内部的函数。闭包函数也是一个函数。
def f1():
def f2():
print('from f2')
return f2
res=f1()
res() #from f2
def f1(url):
def f2():
print(url)
return f2
res=f1('www.taobao.com')
res() #www.taobao.com
两种为函数传参的方式:
a.使用参数的形式
def f1(x):
print(x)
f1(1) #1
b.包给函数
def outter(x):
x=1
def inner():
print(x)
return inner
f=outter(1)
f() #1
2.装饰器:为被装饰器对象添加额外功能,定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外功能。
装饰器的实现必须遵守的两大原则:
a.不修改被装饰对象的源代码
b.不修改被装饰对象的调用方式
3.装饰器的使用
改变源代码
import time
def index():
'''被装饰的函数'''
start=time.time()
print('welcome to index')
time.sleep(1)
end=time.time()
print(f'运行时间是:end-start')
index()
运行结果:
welcome to index
运行时间是:1.0000569820404053
编写重复代码:
import time
def index():
print('index')
time.sleep(1)
def f1():
print('f1')
time.sleep(1)
start=time.time()
index()
end=time.time()
print(end-start)
start=time.time()
f1()
end=time.time()
print(end-start)
运行结果:
index
1.0000574588775635
f1
1.0000569820404053
第一种传参方式:改变调用方式
import time
def index():
print('index')
time.sleep(1)
def time_count(func):
start = time.time()
func()
end=time.time()
print(end-start)
time_count(index)
运行结果:
index
1.0000572204589844
第二种传参方式:包给函数-外包
import time
def index():
print('index')
time.sleep(1)
def time_count(func): #func是真正的index
def wrapper():
start = time.time()
func()
end=time.time()
print(end-start)
return wrapper
res=time_count(index) #res==wrapper
res()
运行结果:
index
1.0010573863983154
4.完善装饰器:
wrapper 的返回值和index的返回值相同
import time
def index():
print('index')
time.sleep(1)
return 123
def time_count(func): #func是真正的index
def wrapper():
start = time.time()
func()
end=time.time()
print(end-start)
return res
return wrapper
f1=time_count(index) #res==wrapper
res=f1()
print(res)
运行结果:
index
1.0010573863983154
123
给index传参的实现:
import time
def index():
print('index')
time.sleep(1)
def home(name):
print(f'welcome name to home page')
time.sleep(1)
return name
def time_count(func): #func是真正的index
def wrapper(*args,**kwargs):
start = time.time()
res=func(*args,**kwargs)
end=time.time()
print(end-start)
return res
return wrapper
res=time_count(home) #res==wrapper
f1=res('nick')
print(f1)
运行结果:
welcome nick to home page
1.0000569820404053
nick
5.装饰器语法糖:在被装饰函数正上方,并且是单独的一行@装饰器
def time_count(func): #func是真正的index
def wrapper(*args,**kwargs):
start = time.time()
res=func(*args,**kwargs)
end=time.time()
print(end-start)
return res
return wrapper
@time_count
def index():
print('index')
time.sleep(1)
return 123
@time_count
def home(name):
print(f'welcome name to home page')
time.sleep(1)
return name
# res=time_count(home) #res==wrapper
f1=home('nick')
print(f1)
f2=index()
print(f2)
运行结果:
welcome nick to home page
1.0000572204589844
nick
index
1.0000572204589844
123
6.装饰器模板:
def deco(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
7.三层的有参装饰器:
usename_list=[]
def sanceng(role):
def login_deco(func):
def wrapper(*args,**kwargs):
usename_inp=input('请输入用户名:')
pwd_inp=input('请输入密码:')
if usename_list:
print('已经登录,无须重复')
res=func(*args,**kwargs)
return res
with open(f'role_info.txt','r',encoding='utf8') as fr:
for role_info in fr:
usename,pwd=role_info.strip().split(':')
if usename==usename_inp and pwd==pwd_inp:
print('登录成功')
usename_list.append(usename)
res = func(*args, **kwargs)
return res
else:
print('登录失败')
return wrapper
return login_deco
@sanceng('admin')
def index (x,y):
print('index')
print('x,y',x,y)
return 123
res=index(10,30)
运行结果:
请输入用户名:ldd
请输入密码:123
登录成功
index
x,y 10 30
以上是关于9.23 闭包和装饰器的主要内容,如果未能解决你的问题,请参考以下文章
python-闭包和装饰器-02-装饰器(decorator)