一、上节回顾和作业讲解:

1、如果这个网页没有被爬取过就真的去访问这个网页,否则就返回之前访问的时候缓存文件中的内容

(重要的例子)

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(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/number1994/p/7941399.html")
print(web_content)
网页爬取和缓存

2、回顾

装饰器:  在不修改一个函数的调用方式的前提下载一个函数的前后添加功能

装饰器的本质:闭包函数

@wrapper      #get_url=wrapper(get_url)

def get_url(url):

  content=urlopen(url).read()

  return content

login :了解原理 

flag=False
def login(func):
    def inner(*args, **kwargs):
        global flag
        if flag==False:
            name=input("用户名:")
            password=input("密码:")
            if name=="liu" and password=="123":
                print("登录成功!")
                flag=True
        if flag==True:
            ret=func(*args,**kwargs)
            return ret
    return inner
@login
def art():
    print("欢迎登录文章页")
def dar():
    print("欢迎登录日志页")
art()
dar()
login登录

log  :必须会:写到文件里

def log(func):
    def inner(*args,**kwargs):
        print("你要调用%s函数了"%func.__name__)
        ret=func(*args,**kwargs)
        return ret
    return inner
@log
def f1():
    print("f1")
@log
def f2():
    print("f2")
f1()
f2()
log

web_content :进阶要求

二、今日内容:

1、可迭代的:__inter__

  列表 字典 元祖 字符串 集合

  iterable  :可迭代的

  判断是否是可迭代的:内部含有__iter__方法的数据类型是可迭代的  ——可迭代协议

print("__iter__"in dir([]))  #True

2、迭代器:__iter__  和__next__  (包含next方法的可迭代对象就是迭代器)

  iterator   :迭代器

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

lst_iter=[1,2,3,4,5]
                    #判断类型
print("__iter__"in dir(lst_iter)) #True print("__next__"in dir(lst_iter)) #False
lst_iter=lst_iter.__iter__() #将可迭代的转换为迭代器
print("__iter__"in dir(lst_iter)) #True print("__next__"in dir(lst_iter)) #True

print(lst_iter.__next__()) #1 迭代循环 print(lst_iter.__next__()) #2

3、总结:

  (1)可迭代的必须含有__iter__方法      #可迭代协议

  (2)迭代器比可迭代的多一个__next__方法

  (3)迭代器:包含__next__,__iter__方法    #迭代器协议

  (4)包含__next__方法的可迭代对象就是迭代器

  (5)迭代器是可迭代的一部分,也就是可迭代的包含迭代器

  #获得迭代器:可迭代的.__iter__()

  #使用迭代器:迭代器.__next__()

4、迭代器的工作原理

  #惰性运算  从前到后依次取值,过程不可逆 不可重复

  #节省内存

print("__iter__"in dir(range(10)))  #True
print("__neat__"in dir(range(10)))  #False
range_iter=range(10).__iter__()  #转换为迭代器
print(range_iter.__next__())     #0  迭代取值
print(range_iter.__next__())      #1  迭代取值

5、用while模拟for循环

(1)for 循环是依赖迭代器的

(2)for循环是让我们更简单的使用迭代器

(3)用迭代器取值不需要关心索引或者Key的取值问题

l=[1,2,3,4,5]
l_iter=l.__iter__()       #将可迭代的转换为迭代器
while True:
    try:
        print(l_iter.__next__())
    except StopIteration:
        break

 6、generator  ------生成器

  最简单的生成器:生成器函数和普通函数之间的区别

       (1)生成器函数中含有yield关键字

  (2)生成器函数调用时不会立即执行,而是返回一个生成器

def g_func():
    yield 1
g=g_func()
print(g.__next__())
#1

7、生成器函数(重要例子)衣服调用

def cloth():
    for i in range(1000):
        yield "衣服%s"%i
g=cloth()
for i in range(50):
    print(g.__next__())
for i in range(50):
    print(g.__next__())