小结

# 8.12
# 闭包函数

# 函数传参的方式一
# def inner(x):
#     print(x)
# inner(1) # 1

# 函数传参方式二(闭包函数,把变量和函数一起包起来,下次要用直接调用)
# def outter(x):
# #     def inner():
# #         print(x)
# #     return inner
# # inner = outter(2)  # inner # f = inner
# # inner() # 2
# # f = outter(2)
# # f() # 2

# 爬虫爬网页
# import requests

# def get_res(url):
#     res = requests.get(url)
#     print(res.txt)
# get_res('https://www.baidu.com/')
# get.res('https://www.baidu.com/')

# 用闭包思想
# def func(url):
#     def get_res():
#         res = requests.get(url)
#         print(res.text)
#     return get_res
# baidu_spider = func('https://www.baidu.com') # baidu_spider = get_res()


# 装饰器
## 装饰器:装饰的工具(函数),这个函数有装饰的作用

# 装饰器本质就是一个函数(A),装饰的对象也是一个函数(B),用函数A去装饰函数B

# 装饰原则:如下
# 1.不改变函数B的调用方式
# 2.不改变函数B的源代码

# def A():
#     '''装饰器'''
#     pass
# def B():
#     '''被装饰的对象'''
#     pass
# B()


# def index():
#     '''被装饰的函数'''
#     print('hello,index')
#
# index()

# 1.打印函数运行的时间
# 1.1 改变了函数体代码,没改变调用方式

# import time
#
# def index():
#     start = time.time()
#     print('hello index')
#     time.sleep(1)
#     end = time.time()
#     print(end - start)
# index()

# 1.1 没改变调用方式,也没有改变源代码,但是不同用

# import time
# def index():
#     '''被装饰的函数'''
#     print('hello,index')
#
# def index1():
#     print('hello,index1')
#
# start = time.time()
# index()
# time.sleep(1)
# end = time.time()
# print(end - start)
#
# start = time.time()
# index1()
# time.sleep(1)
# end = time.time()
# print(end - start)

# 装饰器方式
# import time
# def deco(func): # func = index
#     '''装饰器函数'''
#     def inner():
#         start = time.time()
#         func()
#         time.sleep(1)
#         end = time.time()
#         print(end-start)
#     return inner
#
# def index():
#     '''被装饰的函数'''
#     print('hello,index')
#
# index = deco(index) # index = inner
# index()


import time

def index():
    print('hello,index')
    time.sleep(1)
# 检测index的运行的时间,但是不能改变index的调用方式,一级源代码

#首先写一个装饰器函数

# def deco(func): # func是真正的index
#     '''装饰器函数'''
#     def f1():
#         start = time.time()
#         func() # 真正的index
#         end = time.time()
#         print(end - start)
#     return f1
# index(重新创建的index) = deco(index)#(真正的index)
# aaa = deco(index) # index = f1 = aaa
# index() #f1 / aaa

# import time
# # # def deco(func):
# # #     def f1(*args,**kwargs):
# # #         print(args)
# # #         print(kwargs)
# # #         start = time.time()
# # #         #*args = *(10) 10
# # #         res = func(*args,**kwargs) # 真正的index()
# # #         end = time.time()
# # #         print(end - start)
# # #         return res
# # #     return f1
# # # @deco # 语法糖(更精简的代码) index = deco(index)
# # # def index(x,a = 1):
# # #     print(x)
# # #     print(a)
# # #     print('hello,index')
# # #     time.sieep(1)
# # #     return 123
# # # # 重新创建的index = deco(index真正的index)
# # # index = deco(index) # index= f1
# # # index(10)

# 装饰器模板
# def login(func):
#     def inner(*args,**kwargs):
#         # 登录功能
#         username = input('username')
#         pwd = input('pwd')
#         if username == 'nick' and pwd == '123':
#             print('登录成功')
#             res = func(*args,**kwargs)
#             return res
#         else:
#             print('登录失败')
#     return inner
#
# def time_count(func):
#     def inner(*args,**kwargs):
#         start = time.time()
#         res = func(*args,**kwargs)
#         end = time.time()
#         print(end-start)
#         return res
#     return inner
#
# def outter(func):
#     def inner(*args,**kwargs):
#         # 加功能
#         res = func(*args,**kwargs)
#         return inner
#
# @time_count
# @login
# @outter
# def shopping():
#     print('shopping')
# shopping()
# 三层装饰器:给双层装饰器加参数

# 判断账号密码来自于哪个地方
# def auth(engine):
#     def login(func):
#         def inner(*args, **kwargs):
#             # 登录功能
#             if engine == 'file':
#                 username = input('usrename:')
#                 pwd = input('pwd:')
#                 if username == 'nick' and pwd == '123':
#                     print('登录成功')
#                     res = func(*args, **kwargs)  # shopping()
#                     return res
#                 else:
#                     print('登录失败')
#
#             elif engine == 'db':
#                 print('账号密码来自于数据库,非法请求')
#
#         return inner
#     return login
#
# @auth('db')
# def shopping():
#     print('shopping')

# login = auth('db')  # login = login
# shopping = login(shopping)  # shopping = inner
# shopping() # inner()

# 装饰器模板
## 双层装饰器模板
# def outter(func):
#     def wrapper(*args,**kwargs): # wrapper是未来要运行的函数
#         # 加功能
#         res = func(*args,**kwargs) # func是被装饰的函数
#         return res
#     return wrapper
# @outter
# def shopping():
#     print('shopping')
#
# #三层装饰器:给双层装饰器加参数
# def sanceng(engine):
#     def outtr(func):
#         def wrapper(*args,**kwargs): # wrapper是未来要运行的函数
#             # 加功能
#             print(engine)
#             res = func(*args,**kwargs) #func是被装饰的函数
#             return res
#         return wrapper
#     return outter
# @sanceng('file')
# def shopping():
#     print('shopping')


# 迭代器对象
#迭代就是更新换代,重复,基于上一次结果推出下一次的结果

# 怎样表示能迭代
#可迭代(具有__iter__方法)

# x = 1  # 不可迭代对象
#
# s = 'nick'  # 可迭代对象
# s.__iter__()
# lt = [1, 2, 3]  # 可迭代对象
# dic = {'a': 1, 'b': 2}  # 可迭代对象
# tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象
# se = {1, 2, 3}  # 可迭代对象
# f = open('time.py')  # 可迭代对象

#小结: 字符串、列表、字典、元组(元组只有一个元素必须得加逗号表示)、集合、文件等都是可迭代对象,数字类型和函数不是可迭代对象

# s = 'nick'
# s_iter = s.__iter__()
# print(s_iter.__next__())
# print(s_iter.__next__())
# print(s_iter.__next__())
# print(s_iter.__next__())
# 基于索引(基于上一次结果)通过__next__进行迭代

# dic = {'a':1,'b':2} # 可迭代对象
# dic['a']
# dic_iter = dic.__iter__() #不依赖索引取值#迭代器对象
# print(dic_iter.__next__())
# print(dic_iter.__next__())
# print(dic_iter.__next__())

#s = 'nick'  # 可迭代对象,不属于迭代器对象
# s.__iter__()
# lt = [1, 2, 3]  # 可迭代对象,不属于迭代器对象
# dic = {'a': 1, 'b': 2}  # 可迭代对象,不属于迭代器对象
# tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象,不属于迭代器对象
# se = {1, 2, 3}  # 可迭代对象,不属于迭代器对象
# f = open('time.py')  # 可迭代对象,迭代器对象 迭代器对象:具有__iter__以及__next__方法的叫做迭代器对象

# 只有文件是迭代器对象

# for循环原理 迭代循环

# lt = [1,2,3]
# lt_iter = lt.__iter__()
# while 1:
#     try:
#         print(lt_iter.__next__())
#     except StopIteration:
#         break # for循环原理
# 可迭代对象;迭代器对象 # 不依赖索引取值,而是迭代取值
# for循环
# 1.首先使用iter把lt变成迭代器对象;对于文件也要使用iter方法把文件再一次iter下
# 2.然后使用next方法进行迭代取值
# 3. 判断StopIteration异常,遇到异常终止

# f = open('time.py')
# f_iter = f.__iter__()
# print(id(f_iter))
# f_iter_iter = f_iter.__iter__()
# print(id(f_iter_iter))

#小结
# 可迭代对象:具有__iter__方法的对象就是可迭代对象,除了数字类型和函数外都是可迭代对象
# 迭代器对象:具有__iter__和__next__方法的都是迭代器对象,只有文件

# for循环 == 迭代循环

dic ={'a':1,'b':2}
for i in dic:
    print(i)

# 1. 把lt(可迭代对象/迭代器对象)用__iter__方法转换成迭代器对象
# 2. 使用__next__取出迭代器里的所有值
# 3. 使用__next__方法取尽迭代器中的所有值,一定会报错,通过异常捕捉退出while循环

# 解决了不依赖索引取值