1. 编写有参装饰器基本模板
from functools import wraps
def auth(driver):
def deco(func):
@wraps
def wrapper(*args, **kwargs):
if driver == 'file':
print("基于文件认证")
elif driver == 'mysql':
print("基于mysql认证")
elif driver == 'ldap':
print('基于ldap认证')
else:
print("不支持该driver认证")
return
res = func(*args, **kwargs)
return res
return wrapper
return deco
@auth(driver='file') # @deco # wrapper = deco(index) # index = wrapper
def index():
print("from index")
2. 还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作(2种方式)
dic = {'序号': ('函数对应的功能信息', 函数名的内存地址)}
func_dic = {}
def add_to_dic(function_name):
def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not func_dic:
func_dic['0'] = (function_name, func)
# else:
# max_num = 0
# for key in func_dic:
# key = int(key)
# if key > max_num:
# max_num = key
# func_dic[str(max_num + 1)] = (function_name, func)
# 优化: 使用max + lambda
else:
max_num = max(func_dic, key=lambda k: int(k))
func_dic[str(int(max_num) + 1)] = (function_name, func)
res = func(*args, **kwargs)
return res
return wrapper
return deco
@add_to_dic(function_name='查询余额')
def check_balance():
print("from check_balance")
@add_to_dic(function_name='充值')
def recharge():
print("from recharge")
@add_to_dic(function_name='提现')
def withdraw():
print("from withdraw")
@add_to_dic(function_name='转账')
def transfer():
print("from transfer")
def run():
check_balance()
recharge()
withdraw()
transfer()
run()
print(func_dic)
'''
{
'0': ('查询余额', <function check_balance at 0x000002A68C97E9D0>),
'1': ('充值', <function recharge at 0x000002A68C97EAF0>),
'2': ('提现', <function withdraw at 0x000002A68C97EC10>),
'3': ('转账', <function transfer at 0x000002A68C97ED30>)
}
'''
dic = {'序号': 函数名对应的内存地址}
func_dic = {}
def add_to_dic(number:str):
def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
func_dic[number] = func
res = func(*args, **kwargs)
return res
return wrapper
return deco
@add_to_dic('0')
def check_balance():
print("from check_balance")
@add_to_dic('1')
def recharge():
print("from recharge")
@add_to_dic('2')
def withdraw():
print("from withdraw")
@add_to_dic('3')
def transfer():
print("from transfer")
def run():
check_balance()
recharge()
withdraw()
transfer()
run()
print(func_dic)
'''
{
'0': <function check_balance at 0x000001F2438AE9D0>,
'1': <function recharge at 0x000001F2438AEAF0>,
'2': <function withdraw at 0x000001F2438AEC10>,
'3': <function transfer at 0x000001F2438AED30>
}
'''
3. 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定(订正)
'''
import time
def log_record(func, log_path=r'access.log'):
"""记录日志"""
with open(log_path, 'at', encoding='utf-8') as f:
f.write(f"{time.strftime('%Y-%m-%d %X')} is run function: {func.__name__}\n")
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
log_record(func) # 在被装饰函数func执行完毕以后, 往日志文件中追加一行内容的新功能
return res
return wrapper
'''
# 订正: 要在被装饰对象执行之前就记录日志时间. 因为函数的执行过程可能很长, 函数执行完毕以后, 不能确定函数开始运行的时间
import time
def log_record(func, log_path=r'access.log'):
"""记录日志"""
with open(log_path, 'at', encoding='utf-8') as f:
f.write(f"{time.strftime('%Y-%m-%d %X')} is run function: {func.__name__}\n")
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
log_record(func) # 在被装饰函数func执行之前.
res = func(*args, **kwargs)
return res
return wrapper
4. 基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象(订正)
"""
# 列表
li = [1, 2, 3]
li_iterator = li.__iter__()
while True:
try:
print(li_iterator.__next__())
except StopIteration: # 通过捕捉迭代器取值完毕时出现的异常来控制while循环遍历取值结束的条件: StopIteration
break
'''
1
2
3
'''
# 元组
t = (1, 2, 3)
t_iterator = t.__iter__()
while True:
try:
print(t_iterator.__next__())
except StopIteration:
break
'''
1
2
3
'''
# 字典
dic = {'name': 'egon', 'age': 18, 'sex': 0}
dic_iterator = dic.__iter__()
while True:
try:
print(dic_iterator.__next__())
except StopIteration:
break
'''
# 字典默认迭代取值的是key
name
age
sex
'''
# 集合
set1 = {'name', 'age', 'sex'}
set1_iterator = set1.__iter__()
while True:
try:
print(set1_iterator.__next__())
except StopIteration:
break
'''
name
age
sex
'''
# 文件对象
with open("a.txt", 'w+', encoding='utf-8') as f:
f.write("1\n2\n3\n")
f.seek(0) # t模式: seek的第二个参数不指定, 模式就是0模式
while True:
try:
print(f.__next__(), end='')
except StopIteration:
break
'''
1
2
3
'''
"""
# 订正: 定义一个函数,解决代码的冗余性
def my_iterator(obj):
obj_iterator = obj.__iter__()
while True:
try:
print(next(obj_iterator), end=' ')
except StopIteration:
break
# my_iterator([1, 2, 3]) # 1 2 3 1 3 5 7 9
5. 自定义迭代器实现range功能
def my_range(start, stop, step=1): # 步长默认为1: step=1
while start < stop:
yield start
start += step
res = my_range(1, 10, 2)
for i in res:
print(i, end=' ')