叠加多个装饰器、迭代器、自定义迭代器、...生成式

叠加多个装饰器

========================================================
加载装饰器就是将原函数名偷梁换柱成了装饰器最内层那个wrapper函数
在加载完毕后,调用原函数其实就是在调用wrapper函数

当一个被装饰的对象同时叠加多个装饰器时
装饰器的加载顺序是:自下而上
装饰器内wrapper函数的执行顺序是:自上而下

=======================================================


import time

def timmer(func): #func=wrapper2的内存地址
    def wrapper1(*args, **kwargs):
        print('===================================>wrapper1运行了')
        start=time.time()
        res = func(*args, **kwargs) #===========================>跳到wrapper2去执行了,
        stop=time.time()
        print('run time is %s' %(stop - start))
        return res
    return wrapper1

def auth(engine='file'):
    def xxx(func): # func=最原始那个index的内存地址
        def wrapper2(*args, **kwargs):
            print('===================================>wrapper2运行了')
            name=input('username>>>: ').strip()
            pwd=input('password>>>: ').strip()
            if engine == 'file':
                print('基于文件的认证')
                if name == 'egon' and pwd  == '123':
                    print('login successfull')
                    res = func(*args, **kwargs)
                    return res
            elif engine == 'mysql':
                print('基于mysql的认证')
            elif engine == 'ldap':
                print('基于ldap的认证')
            else:
                print('错误的认证源')
        return wrapper2
    return xxx
'''
@timmer装饰的是
	@auth
	def index()
@auth装饰的是
	def index()
'''
@timmer # index=timmer(wrapper2的内存地址) #index=wrapper1的内存地址
@auth(engine='file') #@xxx #index=xxx(最原始那个index的内存地址) #index=wrapper2的内存地址
def index():
    print('welcome to index page')
    time.sleep(2)

index() #wrapper1的内存地址()

迭代器

灵魂三问:

  • 1.什么事迭代器
    迭代指的是一个重复的过程,每一次重复都是基于上一次的结果而来的
 li = ['a','b','c','d','e']
 li = ('a','b','c','d','e')
 li = 'hello'

 i = 0
 while i < len(li)
	print(li[i])
   	i += 1   
 迭代器指的是迭代取值的工具,该工具的特点是可以不依赖于索引取值
  • 2.为何要用迭代器
    为了找到一种通用的&可以不依赖于索引的迭代取值方法

  • 3.如何用迭代器
    可迭代的对象:但凡内置有.__iter__方法的对象都称为可迭代的对象
    迭代器对象:即内置有.__iter__方法,又内置有.__next__方法
    关于__iter__方法:
    调用可迭代对象的__iter__会得到一个迭代器对象
    调用迭代器对象的__iter__会得到迭代器本身

  • 4.总结迭代器的优缺点:
    优点:

    • 1.提供了一种通用的&可以不依赖于索引的迭代取值方式
    • 2.同一时刻在内存中只有一个值,更加节省内存

    缺点:

    • 1.取指定的值不如索引灵活,并且迭代器是一次性的
    • 2.无法预知迭代器数据的个数
# 可迭代的对象: str,list,tuple,dict,set,文件对象
# 迭代器对象: 文件对象

# 可迭代的对象=====》迭代器对象:调用可迭代对象内置的__iter__方法会有一个返回值,该返回值就是对应的迭代器对象
dic={'x':1,'y':2,'z':3}

iter_dic=dic.__iter__()
# print(iter_dic)
res1=iter_dic.__next__()
print(res1)

res2=iter_dic.__next__()
print(res2)

res3=iter_dic.__next__()
print(res3)

res4=iter_dic.__next__()
print(res4)



print(dic.__iter__().__next__())
print(dic.__iter__().__next__())
print(dic.__iter__().__next__())


dic={'x':1,'y':2,'z':3}
# dic=['a','b','c']
iter_dic=dic.__iter__()

iter_dic=open(r'D:\上海python全栈4期\day13\今日内容',mode='rt',encoding='utf-8')

while True:
    try:
        print(iter_dic.__next__())
    except StopIteration:
        break

# for准确地说应该是迭代器循环,for循环的原理如下:
#1. 先调用in后面那个值的__iter__方法,得到迭代器对象
#2. 执行迭代器.__next__()方法得到一个返回值,然后赋值给一个变量k,运行循环体代码
#3, 循环往复,直到迭代器取值完毕抛出异常然后捕捉异常自动结束循环

dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
print(iter_dic)
print(iter_dic.__iter__())

for k in dic: #iter_dic=dic.__iter__()
    print(k)



with open(r'D:\上海python全栈4期\day13\今日内容',mode='rt',encoding='utf-8') as f:
    for line in f: #iter_f=f.__iter__()
        print(line)

自定义迭代器

  • yield关键字:只能用在函数内
    在函数内但凡包含有yield关键字,再去执行函数,就不会立即运行函数体代码了
    会得到一个返回值,该返回值称之为生成器对象,生成器本质就是迭代器
  • 总结yield:
    • 1.提供一种自定义迭代器的解决方案
    • 2.yield可用于返回值
      yield VS return
      - 相同点:都可以用于返回值
      - 不同点:yield可以暂停函数,yield可以返回多次值,而return只能返回一次值,函数就立刻终止
def func():
    print('=====>第一次')
    yield 1
    print('=====>第二次')
    yield 2
    print('=====>第三次')
    yield 3
    print('=====>第四次')

print(func)

g=func()
print(g.__iter__().__iter__().__iter__() is g)
iter(g)         #g.__iter__()
next(g)         #g.__next__()

res1=next(g)
print(res1)

res2=next(g)
print(res2)

res3=next(g)
print(res3)

res4=next(g)
print(res4)



def my_range(start,stop,step=1):      #自定义迭代器实现range功能  (start,stop)是范围,step是步长 默认为1
    while start < stop:          #while循环,满足start 小于 stop 的情况
        yield start              #返回 start
        start+=step           

res=my_range(1,5,2)     # 1 3

next(res)
next(res)
print(next(res))

for item in res:         #for循环 
    print(item)



for item in my_range(1,5,2):     #for循环验证range功能
    print(item)

…生成器

  • 三元表达式
def max2(x,y):
    if x > y:
        return x
    else:
        return y

x=10
y=20
res= x if x>y else y   #res='条件成立的值' if x > y else '条件不成立的值'
print(res)
  • 列表生成式
l=[]
for i in range(1,11):
    if i > 4:
        res='egg%s' %i
        l.append(res)
print(l)

l=['egg%s' %i for i in range(1,11) if i > 4]
print(l)

names=['egon','lxx','yyx','cw','alex','wxx']
l=[]
for name in names:
    if name != 'egon':
        res='%s_DSB' %name
        l.append(res)
print(l)

l=['%s_DSB' %name for name in names if name != 'egon']
print(l)
  • 生成器表达式
res=(i**2 for i in range(3))
print(res)
print(next(res))
print(next(res))
print(next(res))
print(next(res))


with open(r'D:\上海python全栈4期\day13\今日内容',mode='rt',encoding='utf-8') as f:
    data=f.read()
    print(len(data)) #1025

    res=0
    for line in f:
        res+=len(line)
    print(res)

    res=sum((len(line) for line in f))
    res=sum(len(line) for line in f)
    print(res)

    res=max([len(line) for line in f])
    res=max((len(line) for line in f))
    res=max(len(line) for line in f)
    print(res)
  • 字典生成式
items=[('name','egon'),('age',18),('sex','male')]

dic={}
for k,v in items:
    dic[k]=v
print(dic)

res={k:v for k,v in items if k != 'sex'}
print(res)


res={i for i in 'hello'}
print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值