day13迭代器与生成器

三个作业:

# 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
login_dic = {'alex':False}
def login(func):
    def inner(*args,**kwargs):
        if not login_dic['alex']:
            usrname = input('用户名 : ')
            passwd = input('密  码 : ')
            with open('userinfo') as f:
                for line in f:
                    line = line.strip()
                    usr,pwd = line.split(' ')
                    if usrname.strip() == usr and passwd.strip() == pwd:
                        print('登陆成功')
                        login_dic[usrname] = True
        if login_dic['alex']:
            ret = func(*args,**kwargs)
            return ret
    return inner

@login
def home():
    print('欢迎来到home页')

# home()
# home()
# home()
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
def log(func):
    def inner(*args,**kwargs):
        with open('func.log','a+',encoding='utf-8') as f:
            f.write('%s被调用了\n'%func.__name__)
        ret = func(*args,**kwargs)
        return ret
    return inner

@log
def func1():
    print('我是func1')

@log
def func2():
    print('我是func2')

func1()
func1()
func2()

#如果这个网页没有被爬取过,就真的去访问这个网页,否则,返回之前访问的时候存在文件中的内容
from urllib.request import urlopen

def wrapper(func):
    def inner(*args,**kwargs):
        with open('web','rb') as f:
            web_content = f.read()
        if not web_content:
            web_content = func(*args,**kwargs)
            with open('web','wb') as f:
                f.write(b'aaaaaaaaa'+web_content)
        return web_content
    return inner

# @wrapper
def get_url(url):
    content = urlopen(url).read()
    return content

web_content = get_url('http://www.cnblogs.com/Eva-J/articles/7213953.html')
print(web_content)
# web_content = get_url('http://www.cnblogs.com/Eva-J/articles/7213954.html')
# print(web_content)
# web_content = get_url('http://www.cnblogs.com/Eva-J/articles/7213953.html')
# print(web_content)
#迭代器和生成器



#r 可读    文本操作模式
#w 可写    文本操作模式
#rb 直接操作二进制
#wb 直接操作二进制
# 当你拿到的是纯文字,就用文本操作模式
# 当你拿到的是字节,就用二进制操作的模式

# {'url':'文件名1','url2':''}   os

#装饰器:
    # 在不修改一个函数的调用方式的前提下载一个函数的前后添加功能
#装饰器的本质:闭包函数
装饰器三个作业

一、迭代器

内部含有__iter__方法的数据类型 就是可迭代的对象 —— 可迭代协议

迭代器你可以理解为一个容器,我们从这个容器当中一个接着一个的把值取出来的过程就是迭代的过程

#列表 字典 元祖 字符串 集合
# for item in 'asfj':pass
# for i in 25:
#     print(i)
#'iterable' 可迭代的
# print(dir([]))
# print(dir({}))
# print(dir(5))
#
# print('__iter__' in dir('abc'))
#内部含有__iter__方法的数据类型 就是可迭代的  —— 可迭代协议
ret = 'abc'.__iter__()
# l = ['ha','hei','he']
# lst_iter = l.__iter__()
# print(lst_iter.__next__())
# print(lst_iter.__next__())
# print(lst_iter.__next__())
#迭代器的用法
#可迭代的 === 可迭代对象  python一切皆对象
#迭代器
# print(dir(l))
# print('__iter__' in dir(lst_iter))
# print('__next__' in dir(lst_iter))
# print(set(dir(lst_iter)) - set(dir(l)))
# lst_iter.__next__()

#可迭代的 必须 含有 __iter__方法        #可迭代协议
#迭代器比可迭代的多一个 __next__方法
#迭代器:包含__next__,__iter__方法     #迭代器协议
# 包含__next__方法的可迭代对象就是迭代器
#迭代器是可迭代的 的一部分
#获得迭代器:可迭代的调用 __iter__()
#使用迭代器:迭代器.__next__()

#如何判断一个变量是不是迭代器或者可迭代的
# print('__iter__' in dir([1,2,3,4]))
# print('__next__' in dir([1,2,3,4]))

# from collections import Iterable
# from collections import Iterator
# print(isinstance([1,2,3,4],Iterable))
# str_iter = 'abc'.__iter__()
# print(isinstance(str_iter,Iterator))
# print(isinstance('abc',Iterable))


#可迭代的  : __iter__
#迭代器    : __iter__ 和__next__
#迭代器和可迭代的关系 :可迭代的包含迭代器
#迭代器和可迭代的判断 :两种方法

#迭代器的工作原理
l_iter = [1,2,3,4,5].__iter__()
#只是记录当前这个元素和下一个元素
# print('__iter__' in dir(range(10)))
# print('__next__' in dir(range(10)))
# range_iter = range(10).__iter__()
# print(range_iter.__next__())
# print(range_iter.__next__())
#迭代器的特点  —— 迭代器是个好东西
#惰性运算
#从前到后一次去取值,过程不可逆 不可重复
#节省内存

# for item in [1,2,3]:
#     pass

    #list_iter = [1,2,3].__iter__()
    #list_iter.__next__()

#用while循环模拟for循环的方式  —— for循环是依赖迭代器的,且我们自己也可以仿照着写
# l = [1,2,3,4,5]
# l_iter = l.__iter__()
# while True:
#     try:
#         print(l_iter.__next__())
#     except StopIteration:
#         break

#for循环是让我们更简单的使用迭代器
#用迭代器取值就不需要关心索引或者key的问题了

#迭代器是个好东西
#目前我们已知的可迭代的都是python提供给我们的
#range()
#f
#enumerate()
#在平时写代码的过程中,我们用for循环就够了

二、生成器   生成器就是迭代器

1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

import time
def genrator_fun1():
    a = 1
    print('现在定义了a变量')
    yield a
    b = 2
    print('现在又定义了b变量')
    yield b

g1 = genrator_fun1()
print('g1 : ',g1)       #打印g1可以发现g1就是一个生成器
print('-'*20)   #我是华丽的分割线
print(next(g1))
time.sleep(1)   #sleep一秒看清执行过程
print(next(g1))

制作衣服

def produce():
    """生产衣服"""
    for i in range(2000000):
        yield "生产了第%s件衣服"%i

product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服
num = 0
for i in product_g:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

斐波那契数列

def f1():
    a = 1
    yield a
    b = 1
    yield b
    while True:
        c = a + b
        yield c
        a = b
        b = c
n = 1
for i in f1():
    print(i)
    n +=1
    if n ==10:
        break    # 取前十个

 



 

posted on 2017-11-04 17:55  心如沚水  阅读(188)  评论(0编辑  收藏  举报