闭包函数
闭(封闭/关闭)包(包子/把馅(闭包函数内部的变量)和皮(闭包函数内部的函数)包起来) --》返回闭包函数内部的函数
闭包函数内部的变量+闭包函数内部的函数,这两者包裹在一起
import requests
def f1(url): # f1就叫做闭包函数
def spider():
requests.get(url)
print(url)
return spider # 函数对象
taobao = f1('www.taobao.com')
taobao()
装饰器
新增加了一个额外的功能
装饰器本质就是一个 给函数增加功能的函数
增加功能需要注意一下两点:
- 不改变原函数的源代码
- 不改变原函数的调用方式
案例
# v1
import time
def index():
"""被装饰的函数"""
print('index')
time.sleep(1)
# time_count装饰器:对被装饰函数计时
def time_count(func): # func才是真正的index
"""装饰器"""
def wrapper():
start = time.time()
func()
end = time.time()
print(end - start)
return wrapper
index = time_count(index) # index == wrapper
index() # wrapper()
# v2:带返回值
import time
def index():
"""被装饰的函数"""
print('x',x)
print('index')
time.sleep(1)
return 'index'
# time_count装饰器:对被装饰函数计时
def time_count(func): # func才是真正的index
"""装饰器"""
def wrapper():
start = time.time()
res = func() # index()
end = time.time()
print(end - start)
return res
return wrapper
index = time_count(index) # index == wrapper
res = index() # wrapper()
print(res)
# v3:加参数
import time
def index(x,y,z=10):
"""被装饰的函数"""
print('x',x)
print('index')
time.sleep(1)
return 'index'
# time_count装饰器:对被装饰函数计时
def time_count(func): # func才是真正的index
"""装饰器"""
def wrapper(*args,**kwargs): # (10, 20) # *args和**kwargs接收了所有的参数
start = time.time()
res = func(*args,**kwargs) # index() # *(10,20) # *args和**kwargs打散参数传给真正的index
end = time.time()
print(end - start)
return res
return wrapper
index = time_count(index) # index == wrapper
res = index(10,20,320) # wrapper()
print(res)
登录装饰器
#装饰器模板
def deco(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
二层装饰器:# 1. 用来装饰函数的,它本质是函数# 2. 不改变函数源代码# 3. 不改变函数调用方式
# python装饰器语法糖(就是让代码更简洁)
username_list = []
def login_deco(func):
def wrapper(*args, **kwargs):
if username_list:
print('已经登录,请勿重复登录')
res = func(*args, **kwargs)
return res
username_inp = input('请输入用户名:')
pwd_inp = input('请输入密码:')
with open('user_info.txt', 'r', encoding='utf8') as fr:
for user_info in fr:
username, pwd = user_info.strip().split(':')
if username_inp == username and pwd_inp == pwd:
print('登录成功')
username_list.append(username)
res = func(*args, **kwargs)
return res
else:
print('登录失败')
return wrapper
@login_deco # index = login_deco(index)
def index(x, y):
print('index')
print('x,y', x, y)
return 123
res = index(10, 20)
三层装饰器
username_list = []
def sanceng(role):
def login_deco(func):
def wrapper(*args, **kwargs):
if username_list:
print('已经登录,请勿重复登录')
res = func(*args, **kwargs)
return res
username_inp = input('请输入用户名:')
pwd_inp = input('请输入密码:')
with open(f'{role}_info.txt', 'r', encoding='utf8') as fr:
for user_info in fr:
username, pwd = user_info.strip().split(':')
if username_inp == username and pwd_inp == pwd:
print('登录成功')
username_list.append(username)
res = func(*args, **kwargs)
return res
else:
print('登录失败')
return wrapper
return login_deco
@sanceng('user')
def index(x, y):
print('index')
print('x,y', x, y)
return 123
res = index(10, 20)
迭代器的引入
x = 10
s = 's1'
lt = [1, 2, 3]
# 可迭代对象:含有__iter__方法的就叫做可迭代对象
# 迭代器:含有__iter__和__next__方法的就叫做迭代器
print(x)
print(s)
with open('user_info.txt', 'r', encoding='utf8') as fr:
fr.__next__()
# 生成器:含有yield关键字的函数就叫做生成器