随堂笔记18day

字符串存储到硬盘上的编码流程

字符串——encode——bytes

将bytes形式转化成字符串

bytes——decode——字符串

文件处理模式b模式     rb:以读的模式,以字节的方式去读

f = open(‘test11.py‘,’rb‘, encoding=’utf-8') 会报错

  因为你已经告诉程序使用rb模式读取,就不应该再指定encoding编码,所以b模式不能指定编码

字节是以二进制形式为单位

open()是一个函数,完成一个特定的功能,打开文件

f = open(‘test11.py’,‘rb')

data = f.read()

print(data) ---------------------显示的是字符串的原生模式, 没有实际操作,但是在字符串模式中就会以回车形式显示

print(data.decode('utf-8'))

结果:’hello 2222222 33333 44444'

在window平台中回车是

在linux平台中回车是

f = open('test222.py', 'wb')

f.write(bytes('1111 ', encoding='utf-8')   等同于 f.write(‘海绵宝宝’,encode(‘utf-8’))

f = open ('test22.py', 'ab') 其中‘ab’不代表在最后一行写,应该是在文件光标最后一个位置里写。

f.write('海绵宝宝‘, encode(’utf-8‘))

问题一:为什么用二进制保存

    二进制可以跨平台传输,在window中比较有用,linux默认是以bytes

x = ’hello‘

b = bytes(x.encoding='utf-8')            等同于   x.encode('utf-8')

class(x) ——str

class(b) ——bytes

查看类型class

文件使用的其他方法:

  close  关闭

  closed 判断是否关闭——布尔值,文件关闭返回的是True

  encoding   显示用什么编码,就取什么编码打开             如果不知道原文件的编码就会乱码           

  errors   关于编码的报错 

  flush  刷新——将文件内容从内存刷到硬盘中

          f.flush() 运行文件时,数据是保存在内存里面,pycharm会自动帮你保存(过几秒),所以pycharm是演示不出来,要在终端中演示

  isatty ——是不是终端设备

  name ——文件名

  seek ——控制光标移动

        seek(3)从头开始算,将光标移动到第三个字节

        文件内光标移动:

             注意,read(3)代表是读取3个字符,其余的文件内光标移动都是以字节为单位,如seek,tell,read,truncate

         f.seek(1)——有可能会报错

               因为’你‘是由三个字节组成(utf-8)组成,seek(1)  你    1|23     会报错为无效位置  

  seekable

  tell ——显示光标所在位置

  truncate ——文件截断(要在写的模式什么都行,就是w+不行,会覆盖)

      f.truncate(10):从开头开始算,将文件保留从0-10个字节,文件必须以写的方式打开,但是w和w+除外

  readlines()读一行,读到一行

f =open('b.txt','r', encoding='utf-8', newline=' ')

    其中encoding不指定会默认找操作系统编码,newline是读取文件中真正的换行符号

print(f.readlines())

结果:['你好’ ', 'helloaaaa']             如果没有newline=' ',则没有 ,只有

seek有三种模式

第一种模式(不用指定‘rb’):f.seek(10,0)     其中0是默认参数,从开始作为你的相对位置

第二种模式(相对模式):f.seek(3, 1)      其中1是表示使用第二个模式,表示采用相对位置,相对于上一次位置

第三种模式(文件末尾seek,倒着读就倒着seek):f.seek(10,2)----错误,倒着seek就应该以负数形式。使用在日志文件中使用

                                          写日志时一定要写上时间,分析当前最近的日志,最新的通常在文件最后一行

 seek是按照字节方式seek,所以seek的时候要以‘rb’方式去操作(seek的二和三模式要)

循环文件的推荐方法

for i in f:
    print(i)

读文件最后一行推荐方法(文件内容几个g)

f = open('日志文件','rb')
for i in f:
    offs = -10
    while True:
        f.seek(offs, 2)
        data = f.readlines()
        if len(data)>1:
            print(‘文件的最后一行是%s’%(data[1](‘utf-8')))
            break
        offs *= 2
日志文件读最后一行

不推荐用法

f = open('日志文件’,‘rb’)
data = f.readlines()             #这样会加载文件的所有内容
print(data[-1].decode('utf-8'))

迭代器和递归

迭代器协议是指:

  1.对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stoplteration异常,以终止迭代(只能往后走,不能往前退。可以理解成儿子不可能生父亲)

  2.可迭代对象实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法

  3.协议是一种约定,可迭代对象实现了迭代器协议,python内部工具,(如for循环,sum, min, max,函数等)使用迭代器协议访问对象

            迭代器的好处:用的时候才拿,内存占用率低,用完就回收。

  python中强大的for循环机制

        for循环的本质:循环所有对象,全都是使用迭代器协议

准确来说(字符串, 列表, 元组, 字典, 集合, 文件对象)这些都不是可迭代对象

只有通过for循环式,调用了它们内部的___iter__方式

把它们变成了可迭代对象

然后for循环调用可迭代对象的__next__方法去取值

而且for循环会捕捉stoplteration异常,以终止迭代

不用for循环,用while循环进行遍历适用有序,--------不适用于无序(字典和集合)

index = 0

while index<len(l):

  print( l [index] )

l = [1, 2, 3]

for i in l :     这里会进行两个步骤 1.先调用___iter__放到 l 的地方(转化), 2.进行 l.__next__()  (调用next)

  print(i)

next 内置函数. 

  next是python系统里的内置函数,调用__iter__和___next__()

迭代器就是可迭代对象

生成器 :一种数据类型,自动实现了迭代器协议 (generator object 生成器对象)

  在python里

       生成器函数

       生成器表达式

return——执行就退出

yield——有点类似return值,执行完不会马上结束,可以返回多个值,即好像可以return多次一样

def test():

  yield 1  -------|

  yield 2  ---------------实现生成器协议

  yield 3   -------|

g = test()

print(‘来自函数’,g) ------打印的是生成器

print(g.__next__())

三元表达式,注意不存在四元表达式

name=‘wwe’  

#name =‘海绵宝宝’

res = ‘巴基斯坦炸弹摔’ if name == ‘wwe’ else ‘天真可爱’

  如果是True,返回‘巴基斯坦炸弹摔’

  如果是False,返回‘天真可爱’

print(res)

列表解析——生成一个列表,会放到内存,占用内存。如果数据太大就不推荐使用这个方法

egg_list = [ ]

for i in range(10):

  egg_list.append('鸡蛋%s‘ %i)       ==等同于==   l = ['鸡蛋%s’%i for i in range(10)]

print(egg_list)

l = ['鸡蛋%s’%i for i in range(10)]--------方括号

laomuji = ('鸡蛋%s‘%i for i in range(10))------生成器表达式(圆括号)

print(laomuji) -----打印的是生成器

下蛋 print(laomuji.__next__())   等同于   print(next(laomuji) )

还可以:

l = [ '鸡蛋%s’%i for i in range(10)if i >5 ]

其中:  

  一元:for i in range(10)

  二元: ‘鸡蛋%s’%i

  三元:if i > 5   --------后面不能再写else,写了就是四元,就会报错。

顺序为 三元成立,着传给一元,一元成立传给二元打印

原文地址:https://www.cnblogs.com/chrpy/p/8540344.html