python笔记(16)--迭代器、生成器和logging模块
内容目录
- 迭代器
- 生成器
- 装饰器
- 项目结构
- logging模块
内容回顾&补充
1.内容回顾
1.1函数(内置/自定义)
-
基本函数结构
def func(a1,a2): pass
- 参数
- 返回值
- 执行函数
-
函数小高级
- 函数做变量
- 函数做参数
-
函数中高级
- 函数做返回值
- 函数的嵌套
-
装饰器 & 闭包
-
递归(函数自己调用自己)
-
匿名函数(labma)
-
内置函数
1.2模块(内置/第三方/自定义)
- 定义模块
- 内置:time / json / datetime / os / sys....【re模块(正则表达式使用)】
- 第三方
- 安装:
- pip包管理工具:pip install xlrd(可以满足基本需求)
- 源码安装:(作者没有上传到pip包管理工具时使用这个)
- 下载源码包:压缩文件。
- 解压文件
- 打开cmd窗口,并进入此目录:cd 文件夹的绝对路径
- 执行:python36 setup.py build
- 执行:python36 setup.py install
- 安装路径:C:\python36\Lib\site-packages
- 安装:
- 自定义
- py文件
- 文件夹 ——init——.py
- 调用模块
- import
- import 模块1 模块1.函数()
- import 模块1.模块2.模块3 模块1.模块2.模块3.函数()
- import 文件夹 加载
__init__.py
文件夹内不加载
- from xx import xxx
- from 模块.模块 import 函数 函数()
- from 模块 import 函数 as f f()
- from 模块 import * 函数1() 函数2()
- from 模块 import 模块 模块.函数()
- from 模块 import as m m.函数()
- from 模块.模块 import * 函数1() 函数2()
- 加载的是
__init__.py
文件夹内不加载
- 加载的是
- import
1.3其他
- 两个值数据交换
- 推导式
- 列表(重要)
- 字典
- 集合
今日内容
1.类和对象(通用叫法)
类 int str list datetime bytes
对象 v=1 v='sda' v=[1,2,3]
2.迭代器
- 自己不会写迭代器,只用。
例如:请展示列表中所有的数据。
-
while + 索引 + 计数器
-
迭代器,对某种对象(str / list / tuple / dict / set类创建的对象)-可迭代对象 中的元素进行逐一获取,表象:具有
__next__()
方法且每次调用都获取可迭代对象中的元素(从前到后一个一个获取)。-
列表转换迭代器:
- v1 = iter([11,22,33,44])
- v1 = [11,22,33,44].
__iter__
()
-
迭代器想要获取每个值:反复调用val = v1.
__next__
()v1 = [11,22,33,44] v2 = iter(v1) #列表转换成迭代器 result1 = v2.__next__() print(result1) result2 = v2.__next__() print(result2) result3 = v2.__next__() print(result3) result4 = v2.__next__() print(result4) #等同于for循环 while True: try: val = v2.__next__() print(val) except Exception as e: break
-
直到报错:Stoplteration错误,表示已经迭代完成。
-
如何判断一个对象是否是迭代器:内部是否有
__next__
()方法
-
-
for循环
v1 = [11,22,33,44] #1.for循环内部会把V1转换成迭代器 #2.内部反复执行,迭代器.__next__() #3.取完值后不报错 for item in v1: print(item)
3.可迭代对象
-
什么是可迭代对象,迭代对象与迭代器的关系
-
内部可以使用
__iter__
()方法的,能被for循环的,称为可迭代对象 -
两者的关系:迭代对象可转换为迭代器
-
4.生成器(函数的变异)
类:generator
#函数
def func():
return 132
func()
#生成器函数(内部是否包含yield)
def func():
print('f1')
yield 1
print('f2')
yield 2
print('f3')
yield 3
print('f4')
val = func() #函数内部代码不会执行,此时val等于generator类型的函数对象
# 生成器是可以被for循环,一旦开始循环那么函数内部代码就会开始执行
for item in val:
print(item) #每次遇到yield时拿到后面的返回值,yield只能被for循环才能打印
def func():
count = 1
while count <= 100:
yield count
count += 1
val = func()
for item in val:
print(item)
import time
def func():
"""
分批去读取文件中的内容,将文件的内容返回给调用者。
:return:
"""
cursor = 0
while True:
f = open('log.txt', 'r', encoding='utf-8')# 通过网络连接上redis
# 代指 redis[0:10]
f.seek(cursor)
data_list =[]
for i in range(10):
line = f.readline()
if not line:
return
data_list.append(line)
cursor = f.tell()
f.close() # 关闭与redis的连接
for row in data_list:
yield row
for item in func():
print(item)
time.sleep(3)
总结:
- 函数内部无论是否执行,只要有yield时,此函数就被定义为生成器函数
- 调用生成器函数时会返回一个生成器,生成器只有被for循环时,才会执行内部代码。
- 每次循环都会获取yield返回的值。
#谨记特殊情况
def func():
return 123
yield 1
yield 2
val = func() #此时val是一个生成器函数对象,无论是否执行。
for item in val: #item没有值,因为return直接终止了函数,yield没有传值给item
print(val)
yield from生成器嵌套:
-
yield from 关键字
- python 3.3版本后才有的,之前没有这个功能
def base(): yield 88 yield 99 def func(): yield 1 yield 2 yield from base() yield 3 result = func() for item in result: print(item) #结果为1,2,88,99,3
生成器推导式:
- 跟列表生成式很像,但是不一样,大多数用列表推导式,生成器推导式用的不多
v1 = [i for i in range(10)] #列表推导式,立即循环创建所有元素
#列表推导式相当于:
def func():
result = []
for i in range(10):
result.append(i)
return result
v1 = func()
v2 = (i for i in range(10)) #生成器推导式,创建了一个生成器,内部循环未执行
#生成器推导式相当于:
def func():
for i in range(10):
yield i
v2 = func()
#取值才能取出
for i in v2:
print(i)
总结:
-
迭代器
- 对可迭代对象中的对象逐一获取,迭代器对象的内部都有一个
__next__
()方法,用于一个个获取数据
- 对可迭代对象中的对象逐一获取,迭代器对象的内部都有一个
-
可迭代对象
- 可以被for循环且此类对象中都有
__iter__
()方法且要返回一个迭代器(或生成器)。
- 可以被for循环且此类对象中都有
-
生成器
-
函数内部只要有yield就是生成器函数,调用函数只会返回生成器函数,循环生成器时,则函数内部才会执行。
-
生成器内部也有
__next__
()方法和__iter__
(),所以也可被称为迭代器或迭代对象 -
def func(): yield 1 yield 2 yield 3 v = func() result = v.__next__() print(result) result = v.__next__() print(result) result = v.__next__() print(result) result = v.__next__() print(result)
-
def func(): yield 1 v = func() result = v.__iter__() print(result)
-