1.以字节方式读取文件
f=open("chengli1",'rb')#b方式读时不能指定编码
data=f.read()
print(data)
window下回车是:\r\n
Linux下回车是:\n
如果要解码
print(data.decode('utf-8'))
f.close
2.文件操作的其他方法
f.flush()#写入的数据还在内存,flush将立即写入硬盘
f.tell()当前在哪个位置
f=open('b.txt','r',encoding='utf-8',newline='')#添加newline=''读取文件中真正的回车换行符
否则Python将读取的回车换行统一转换为\n,读到window下的\r\n也是转为\n
f.seek(0)控制光标的位置
只要不是read方法,其余的在处理光标的时候,统一都是按照字节为单位
f.seek(10)光标从0开始移动到绝对位置10
f.seek(3,1)移动到相对位置,相对前一次位置
f.seek(-10,2)倒序移动10个
f.truncate(10)从开头到10截取,其余的删除
使用r+或a+打开文件,如果使用w+打开文件则文件被清空
3.读日志文件
f= open("日志文件","rb")
data=f.readlines()
print(data[-1].decode('utf-8'))#读最后一行就是列表的最后一个
使用seek读取最后一行:
f= open("日志文件","rb")
#循环文件的推荐方式
for i in f:
print(i)
倒序读
for i in f:
offes =-10
while True:
f.seek(offes,2)#倒序读10个数据
data=f.readlines()
if len(data)>1:#读取的列表有两个数据,代表已经读了2行
print('文件的最后一行是%s' %(data[-1].decode('utf-8')))
break
offes*=2##没有读到两行时扩大范围再次读
4.迭代器协议和生成器
递归:每次调用自己,嵌套返回
迭代:只能往后走不能向前 for循环
5.迭代协议:对象必须提供一个next方法,执行该方法返回迭代的下一项,或引起一个异常
可迭代对象:实现了迭代器协议的对象(对象内部定义一个__iter__()方法)
(字符串、列表、元组、字典、集合、文件对象)这些都不是可迭代对象,只不过在for循环式,调用了
他们内部的__iter__方法,把他们变成了可迭代对象
用下标的方式可以遍历列表,为何要用for循环得迭代器
因为有些对象是字典和集合等非序列对象,就需要使用迭代,因为没有下标
for循环做两件事:1调用对象的__iter__方法转为可迭代对象 2迭代
print(iter_l.__nest__())
等于print(next(iter_l))
6.生成器
一种数据类型,这种类型自动实现了迭代器协议
生成器函数:常规函数定义,但是使用yield语句而不是return语句
def test():
yield 1
yield 2#可以多个
yield 3
g=test()
print(g)
g.__next__()
生成器表达式:三元表达式
'sb' if name=='alex' else 'shuaige'
如果if结果为真 返回 'sb'假 返回'shuaige'
三元表达式的应用:列表解析
egg_list=[]
for i in range(10):
egg_list.append('鸡蛋%s'%i)
print(egg_list)
结果:['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡
蛋9']
使用三元表达式:
l=['鸡蛋%s'%i for i in range(10)]
print(l)
l=['鸡蛋%s'%i for i in range(10) if i>5]
l=['鸡蛋%s'%i for i in range(10) if i>5 else i]#错误,没有四元表达式
改为生成器
laomuji=("鸡蛋%s" %i for i in range(10))
print(laomuji)
print(laomuji.__next__())
print(laomuji.__next__())
print(next(laomuji))
结果:
<generator object <genexpr> at 0x013F51B0>
鸡蛋0
鸡蛋1
鸡蛋2
7.总结:
把列表解析的[]换成()得到的就是生成器表达式
列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存(生成器表达式调
用一次生成一个,而不是一次性全部生成)
8.sum参数中使用生成器表达式
print(sum(i for i in range(1000000)))
结果:499999500000
9.
def test():
print("生孩子...")
yield '我'
print("生儿子...")
yield '儿子'
print("生孙子...")
yield '孙子'
res=test()
print(res)
print(res.__next__())
print(res.__next__())
print(res.__next__())
结果:<generator object test at 0x01C45230>
生孩子...
我
生儿子...
儿子
生孙子...
孙子
执行一次next,停止到一个yield后