标签:认证 生成器 word 通用 username code start 其他 遍历
装饰器语法糖
无参装饰模板
叠加多个装饰器
# 需求:在不修改index函数的源代码和调用方式的前提下为其添加统计运行时间的新功能
import time # 导入时间模块
def index(): # 一个函数
time.sleep(1) # 模拟index运行的一点时间 源代码
print(‘from index‘) # 源代码
index() # 调用方式
# 方案一:失败
# 问题:确实添加了新功能,但是修改了源代码
import time
def index():
start = time.time() # 统计开始时间
time.sleep(1)
print(‘from index‘)
stop = time.time() # 统计结束时间
print(‘run time is %s‘ %(stop - start))
index()
# 方案二:失败
# 问题:看似装饰器的效果实现了,但是引发了重复代码的问题
import time
def index():
time.sleep(1)
print(‘from index‘)
start = time.time()
index()
stop = time.time()
print(‘run time is %s‘ %(stop - start))
# 方案三:失败
# 问题:把要装饰的代码丢进函数里,为的是重复调用,但是把index写死了,就无法用上装饰器
import time
def index():
time.sleep(1)
print(‘from index‘)
def wrapper():
start = time.time()
index()
stop = time.time()
print(‘run time is %s‘ %(stop - start))
wrapper()
wrapper()
# 方案四:失败
# 问题: 把index函数名变成变量名func,要为wrapper函数的函数体代码传参数,
# 直接用参数传参,装饰对象虽然写活了,但只能装饰index
import time
def index():
time.sleep(1)
print(‘from index‘)
def wrapper(func):
start = time.time()
func() # 被装饰函数
stop = time.time()
print(‘run time is %s‘ %(stop - start))
wrapper(index)
# 方案五:====》闭包函数
import time
def index(): # index = 被装饰对象index函数的内存地址
time.sleep(1)
print(‘from index‘)
def outter(func): # func = 被装饰对象index函数的内存地址
def wrapper():
start = time.time()
func() # 被装饰对象index函数的内存地址
stop = time.time()
print(‘run time is %s‘ %(stop - start))
return wrapper # 千万别加括号
# outter=(被装饰对象index函数的内存地址)
index = outter(index) # outter-》返回wrapper函数的内存地址-》index = wrapper函数的内存地址
print(index)
index()
# 方案六:====》将wrapper伪装成被装饰的函数,name应该装的尽可能像一些
import time
def index(): # index = 被装饰对象index函数的内存地址
time.sleep(1)
print(‘from index‘)
def home(name):
time.sleep(2)
print("welcome %s to home page" %name)
return 123
def outter(func): # func = 被装饰对象index函数的内存地址
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs) # 被装饰对象index函数的内存地址(x,y,z)
stop = time.time()
print(‘run time is %s‘ %(stop - strt))
return res
return wrapper
index = outter(index)
home = outter(home) # 偷梁换柱:home这个名字指向的wrapper函数的内存地址
res = home("geng") # wrapper("geng")
print(res)
res = index() # wrapper()
print(res)
import time
from functools import wraps
def outter(func): # func = 被装饰对象index函数的内存地址
@wraps(func)
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs) # 被装饰对象index函数的内存地址(x,y,z)
stop = time.time()
print(‘run time is %s‘ %(stop - start))
return res
return wrapper # 千万别加括号
# 在被装饰对象正上方的单独一行写@装饰器名字
@outter # index = outter(index) # outter(被装饰对象index函数的内存地址) -> 返回wrapper
# 函数的内存地址---> index = wrapper函数的内存地址
def index(): # index = 被装饰对象index函数的内存地址
"""这是index函数"""
time.sleep(1)
print(‘from index‘)
@outter # home = outter(home)
def home(name):
time.sleep(2)
print("welcome %s to home page" %name)
return 123
# res = home("egon") # wrapper("egon")
# print(res)
# res = index() # wrapper()
# print(res)
print(index.__name__)
print(index.__doc__)
# 闭包函数 函数 (被装饰函数)
def outter(func):
def wrapper(*args,**kwargs): # wrapper函数,在wrapper内写被装饰的函数
res = func(*args,**kwargs) # *args,**keargs让参数保持一致,装的像一点
return res # 让返回值保持一致,装的像一点
return wrapper
# 以上的装饰器为被装饰对象啥新功能也没添加,就是无参装饰器模板
# 认证功能装饰器模板
def login(func):
def wrapper(*args,**kwargs):
name = input(‘username>>>: ‘).strip()
pwd = input(‘password>>>: ‘).strip()
if name == ‘egon‘ and pwd == "123":
res = func(*args,**kwargs)
return res
else:
print(‘账号密码错误‘)
return wrapper
@login
def index():
print(‘index‘)
index()
def deco1(func1): # func1 = wrapper2的内存地址
def wrapper1(*args,**kwargs):
print(‘==========>wrapper1‘)
res1 = func1(*args,**kwargs)
print(‘end1‘)
return res1
return wrapper1
def deco2(func2): # func2 = wrapper3的内存地址
def wrapper2(*args,**kwargs):
print(‘=========>wrapper2‘)
res2 = func2(*args,**kwargs)
print(‘end2‘)
return res2
return wrapper2
def deco3(func3): # func3 = 被装饰index的内存地址
def wrapper3(*args,**kwargs):
print(‘=========>wrapper3‘)
res3 = func3(*args,**kwargs)
print(‘end3‘)
return res3
return wrapper3
# index = wrapper1的内存地址
@deco1 # deco1(wrapper2的内存地址) -> wrapper1的内存地址
@deco2 # deco2(wrapper3的内存地址) -> wrapper2的内存地址
@deco3 # deco3(被装饰index的内存地址)-> wrapper3的内存地址
def index():
print(‘index......‘)
index()
nums = [111, 222, 333] # 遍历列表,索引,迭代取值
nums = "hello" # 遍历字符串,索引,迭代取值
def get(l): # 函数就是取值工具
i = 0
while i < len(l):
print(l[i])
i += 1
get(nums)
# 内置的类型都是可迭代的对象
"abc" # 字符串
[1,2,3] # 列表
(1,2,3) # 元组
{‘k1‘:111} # 字典
{1,2,3} # 集合
f = open(‘a.txt‘,mode=‘wt‘) # 文件对象本身就是迭代器对象
# 例1:
# 迭代器直接取值方式
nums = [111,222,3333]
nums_iter = nums.__iter__() # 将可迭代对象转为迭代器版本,源列表没动,产生新的
print(nums_iter)
print(nums_iter.__next__())
print(nums_iter.__next__())
print(nums_iter.__next__())
print(nums_iter.__next__()) # 抛出异常 StopIteration
x = iter(nums)
print(next(x))
print(next(x))
print(next(x))
# 例2:
# 用while循环解决迭代器取值
nums = [111,222,3333]
nums_iter = iter(nums) # 把可迭代对象先转成迭代器对象
while True:
try: # 异常处理,next到第四次检测出异常
res = next(nums_iter)
print(res)
except StopIteration: # 捕捉异常,结束循环
break
# 1、先调用in后那个对象的__iter__方法,拿到迭代器对象
# 2、 res = next(迭代器对象),执行一次循环体代码
# 3、循环往复步骤2,直到值取干净抛出异常StopIteration,for会捕捉异常结束循环
nums = [111,222,3333] # 用for循环两行代码解决例2
for res in nums:
print(res)
1、为序列和非序列类型提供了一种统一的迭代取值方式。
2、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内
? 存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大
? 小的限制,可以存放的值的个数是有限的。缺点
? 1、除非取尽,否则无法获取迭代器的长度
? 2、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法 直到值取尽,否则就会
? 停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,
? 如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
def func():
print(‘xxx‘)
yield 111
print(‘yyy‘)
yield 222
print(‘zzz‘)
yield 333
print(‘mmmm‘) # 报错,抛出异常 StopIteration 取到这里就取干净了
# 当函数内出现yield关键字,再调用函数并不会触发函数体代码的运行,会返回一个生成器
g = func()
# print(g) # 生成器就是一种自定义的迭代器
res = next(g)
print(res)
res = next(g)
print(res)
res = next(g)
print(res)
next(g)
# 例:
# 一出场就是一只老母鸡,可以存无穷个值的类型,但每次只能拿一个
def func():
res = 1
while True:
yield res
res += 1
g = func() # 得到一个迭代器
print(next(g)) # 打印next触发代码运行,可以返回无数个值
print(next(g))
print(next(g))
nums =[111,22,33]
x = iter(nums)
for res in x: # x.__iter__()
print(res)
print(‘=‘*50)
for res in x: # x.__iter__()
print(res)
for res in nums: # nums.__iter__()
print(res)
print(‘=‘*50)
for res in nums: # nums.__iter__()
print(res)
标签:认证 生成器 word 通用 username code start 其他 遍历
原文地址:https://www.cnblogs.com/gfeng/p/14213135.html