• 文件操作以及序列化


    计算机系统分为:硬件,操作系统,应用程序
    硬件:目的在于运行软件发出的指令。硬件包括CPU,内存,硬盘
    多数CPU都有两种模式,即内核态与用户态。        
    ①当cpu处于内核状态时,运行的是操作系统,能控制硬件(可以获取所有cpu的指令集)     
    ②当cpu处于用户太状态时,运行的是用户软件,不能控制硬件(可以获取所有cpu的指令集中的一个子集,该子集不包括操作硬件的指令集)

     

    关于文件:

    • 文件可以存储不同类型的信息,一个文件可以包含文本,图片,视频,计算机程序等内容。
    • 计算机上硬盘上所有的内容都是以文件的形式存储。程序就是由一个或者多个文件构成的。
    • 文件对象是python代码对电脑上外部文件的主要接口。

    文件属性:

      名字

      类型(表明文件数据类型,是图片,音乐,还是文本

      位置(存储在哪里)

      大小(文件中有多少字节)

    文件名:

      大多数操作系统中(包括 Windows),文件名中有一部分用来指示文件中包含什么类型的数据。文件名中通常至少有一个点(.),点后面的部分指出了文件的类型。这一部分称为扩展名(extension)

    如:my_letter.txt中的扩展名是.txt,代表“文本”,

      my_letter.exe中,扩展名.exe,代表“可执行文件”

     文件基础用法提示:

    文件迭代器是最好的读取行工具
    内容是字符串,不是对象  
    close时通常选项,调用close会终止对外部文件的连接
    文件是缓冲的并且是可查找的

    关于文件路径问题:

      每个文件都要存储在某个地方,所以除了文件名以外,每个文件还有相应的位置,硬盘和其他存储介质都组织为文件夹或目录。

      文件夹(folder)和目录(directorie)表示的是同一样东西,只是名字不同而已。文件夹或目录组织和关联的方式称为文件夹结构或目录结构。

      位于其他文件夹中的文件夹称为子文件夹(subfolder),如果用目录描述则成为子目录(subdirectory)

     

    该文件路径:‪C:python36Toolsscripts\__pycache__

    tips:斜线(和/)的正确使用,在路径名中这两者都接受,但是为了防止报错,最好使用/,如果使用有时候会和后面字母形成转译符,如 ,如果你非要使用,可以采用\

    上面路径被称为绝对路径:从根目录开始,一级一级查找文件,直到找到文件。

         另外还有相对路径:在同一文件夹下,直接写文件名即可。

    4.1操作文件流程:

    操作文件前必须的记住,文件以什么编码方式存储,就要以什么编码方式打开,否则会很容易报错。

    #1. 打开文件,得到文件句柄并赋值给一个变量
    f=open('a.txt', mode = 'r', encoding='utf-8')   #默认打开模式就为r
    
    #2. 通过句柄对文件进行操作
    data=f.read()  # 读取文件内容
    data = f.readlines() # 读取文件的所有行,直至文件末尾,包括每行换行字符 ,输出的是一个列表 data = f.readline() # 一次只读取文件的一行,如果再在一个程序中使用它,python会记住当前位置,第二次使用会得到第二行 ,输出的是字符串 data = f.read(n) #
    在r模式下,read(n)按照字符去读取。在rb模式下,read(n)按照字节去读取。

    循环读取:
    f = open('log.txt',encoding='utf-8')
    for i in f:
      print(i.strip()) # 每次读取一行,好处在于节省内存
    f.close()
    f.seek(0)   #如果使用了好几次readline,现在想退回到文件起始位置,可以使用该方法。其中括号里的数字是从文件起始位置算起的字节数
    #
    3. 关闭文件 f.close() #这个步骤很关键,可以帮助节省资源

    关闭文件注意事项: 打开一个文件包含两部分资源:操作系统级打开的文件
    +应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
    1、f.close() #回收操作系统级打开的文件 2、del f #回收应用程序级的变量 其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源, 而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()

    with关键字管理上下文:
    #功能一:自动关闭文件句柄。
    #功能二:一次性操作多个文件句柄。
    with open('a.txt','w') as f: 
      
    pass
    with open(
    'a.txt','r') as read_f,open('b.txt','w') as write_f:
      data
    =read_f.read()
      write_f.write(data)

     4.2文件编码

    f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,
    操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。 若要保证不乱码,文件以什么方式存的,就要以什么方式打开。 f=open('a.txt','r',encoding='utf-8')

     4.3文件的打开模式

    打开主要分两种类型:
    文本文件:这些文件包含了文本,包括字母、数字、标点符号和一些特殊字符,如换行符。
    二进制文件:这些文件不包含文本,它们可能包含音乐、图片或其他类型的数据。这些文件中不包含文件,所以没有行,不存在换行符。
          (间接性说明不能对二进制文件使用readline()或者readliners())

         # 大多数情况下,若果需要使用二进制文件,就要通过pygame或者其他一些模块来加载文件

    #
    1. 打开文本文件模式有:
    • r, 只读模式【默认模式,文件必须存在,不存在则抛出异常】
    • w, 只写模式【不可读;不存在则创建;存在则清空内容】
    • x, 只写模式【不可读;不存在则创建,存在则报错】
    • a, 追加模式【可读;不存在则创建;存在则只追加内容】
    #2. 对于非文本文件(二进制文件),我们只能使用b模式,"b"表示以字节的方式操作
    (而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
    rb或r+b,读写
    wb或w+b,写读
    ab或a+b,写读
    注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
    
    #3,‘+’模式(就是增加了一个功能)
    r+, 先读,后追加。一定要先读后写
    w+, 先写,后读(这个其实作用并不大,写完光标已经到最后,打印啥都没有,必须还需把光标移到前面才能读)
    a+, 追加,再读(这个也一样)
    练习,利用b模式,编写一个cp工具,要求如下:
    既可以拷贝文本又可以拷贝视频,图片等文件
    
    1 # b模式
    2 f=open('1.jpg','rb')
    3 data=f.read()
    4 # print(data)
    5 f=open('2.jpg','wb')
    6 f.write(data)
    7 print(data) 

    一,用python创建一个新文件,内容是0到9的整数,每个数字占一行

    f = open('f.txt','w')
    for i in range(0,10):
        f.write(str(i)+'
    ')

    二,文件内容追加,从0到9的10个随机整数,每个数字占用一行

    import random
    f = open('a.txt', 'a')
    for i in range(10):    #这一步作用在于让下面程序运行十次
        f.write(str(random.randint(0, 10)))
        f.write('
    ')    # 这一步其实也可以和上一步合并起来
    f.close()

    三、文件内容追加,从0到9的随机整数, 10个数字一行,共10行

    import random
    f = open('f.txt','a')
    for i in range(0,10):
        for i in range(0,10):
            f.write(str(random.randint(0,9)))
        f.write('
    ')
    f.close()

     逐行读取文件内容的两种方法:

    for line in open('f.txt'):
        print(line)
    
    or:
    f =open('f.txt','r')
    lines =f.readlines()  
    for i in lines:
        print(i)

    4.4文件操作方法

    4.4.0常用操作方法

     read(3):

      1. 文件打开方式为文本模式时,代表读取3个字符
      2. 文件打开方式为b模式时,代表读取3个字节
    其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate
    注意:
      1. seek()是以bytes为单位移动的,按照字节调整光标位置
      2.tell()是按字节读取光标位置
      3. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果。
    1 import time
    2 with open('test.txt','rb') as f:
    3     f.seek(0,2)
    4     while True:
    5         line=f.readline()
    6         if line:
    7             print(line.decode('utf-8'))
    8         else:
    9             time.sleep(0.2)

    4.4.1 序列化

      程序运行中,所有变量都是在内存里面,可以随时修改变量,但是一旦程序结束,变量所占用的内存就会被操作系统全部回收。修改后的变量如果没有储存到磁盘上,下次打开又会初始化成原来的值。

      变量从内存中变成可存储或可传输的过程称之为序列化(python中称为packling)。序列化之后,就可以把内容写入磁盘,或通过网络传输到其他磁盘上

    4.4.2 在文件中保存内容(文件的序列化)

    》》》》》》》》模块链接

    这里一般会用到pickle模块(它只能用于python,不同的python版本之间可能也不兼容)

    或者json模块(可以在不同的编程语言之间传递对象,而且json表示出来就是一个字符串,可以被所有语言取代)

    eval内置函数:

      该函数能够把字符串当作可执行代码运行,但是安全性较差,后面推荐使用hasattr映射

    x, y, z = 43, 44, 45
    S = 'splm'
    D = {'a': 1, 'b': 2}
    L = [1, 2, 3]
    
    F = open('file.txt', 'w')
    F.write(S + '
    ')
    F.write('%s%s%s
    ' % (x, y, x))
    F.write(str(L) + '$' + str(D) + '
    ')
    F.close()    
    # 通过以上步骤将内容写入文件中
    
    chars = open('file.txt')    # 打开文件
    line = chars.readline()    # 只读取一行
    line_two = chars.readline()
    line_three = chars.readline()
    print(line_three)
    parts = line_three.split('$')  
    print(parts)     #   ['[1, 2, 3]', "{'a': 1, 'b': 2}
    "]
    print(eval(parts[1]))    #通过eval函数执行程序代码
    
    temp = [eval(i) for i in parts]
    print(temp)    #  [[1, 2, 3], {'a': 1, 'b': 2}]

     4.5 文件补充

    4.6文件的修改(利用os模块)

    列出当前目录下的所有目录:

    [x for x in os.listdir('.') if os.path.isdir(x)]

    要列出所有的 .py 文件,也只需一行代码:

    [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']

    4.7 文件删除和重命名

    文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,修改文件具体分为以下几步:
    1,将原文件读取到内存。
    2,在内存中进行修改,形成新的内容。
    3,将新的字符串写入新文件。
    4,将原文件删除。
    5,将新文件重命名成原文件。

    Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。要使用这个模块,你必须先导入它,然后才可以调用相关的各种功能。

    重命名和删除文件:

    import os
    #重命名文件,旧文件名f.txt,新文件名file.txt
    os.rename('f.txt','file.txt')
    import os
    os.remove('stdout.txt'
     
    方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
    import os       # 调用系统模块
    
    with open('a.txt') as read_f, open('.a.txt.swap','w') as write_f:
      data=read_f.read()         #全部读入内存,如果文件很大,会很卡
      data=data.replace('alex','SB')      #在内存中完成修改
      write_f.write(data)      #一次性写入新文件
      os.remove('a.txt')           #删除原文件
      os.rename('.a.txt.swap','a.txt')      #将新建的文件重命名为原文件

     方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

    import os
    
    with open('a.txt') as read_f, open('.a.txt.swap','w') as write_f:
      for line in read_f:
        line=line.replace('alex','SB')
        write_f.write(line)
    
    os.remove('a.txt')
    os.rename('.a.txt.swap','a.txt')

    例题:

    有如下文件:

    -------

    alex是老男孩python发起人,创建人。

    alex其实是人妖。

    谁说alex是sb?

    你们真逗,alex再牛逼,也掩饰不住资深屌丝的气质。

    ----------

    将文件中所有的alex都替换成大写的SB。

    import os
    with open('a.txt', mode='r', encoding='gbk') as f,
        open('b.txt', mode='w', encoding='gbk') as f1:
        for i in f:
            if 'alex' in i:
                a = i.replace('alex', 'SB')
                f1.write(a)
    os.remove('a.txt')
    os.rename('b.txt', 'a.txt')
    覆盖的思想

    文件a.txt内容:每一行内容分别为商品名字,价钱,个数。

    apple 10 3

    tesla 100000 1

    mac 3000 2

    lenovo 30000 3

    chicken 10 3

    通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......] 

    lis = []
    sums = 0
    f = open('a.txt', mode='r', encoding='utf-8')
    for i in f:
        s = i.strip().split(' ')
        a = dict([('name', s[0]), ('price', int(s[1])), ('amount', int(s[2]))])
        lis.append(a)
        sums += int(s[1])*int(s[2])
    f.close()
    print(lis)
    low way
    with open('a.txt',encoding='utf-8') as f1:
        for i in f1:
            l2 = i.strip().split()           #l2 = [apple,10,3,2004]
            dic = {}
            for j in range(len(l2)):
                dic[name_list[j]] = l2[j]    # dic[name] = apple dic[price] = 10
            l1.append(dic)
    print(l1)
    注重编程思想

    文件a1.txt内容:每一行内容分别为商品名字,价钱,个数。
    文件内容:

    name:apple price:10 amount:3 year:2012
    name:tesla price:100000 amount:1 year:2013


    通过代码,将其构建成这种数据类型:
    [{'name':'apple','price':10,'amount':3},
    {'name':'tesla','price':1000000,'amount':1}......]

    with open('a1.txt', mode='r', encoding='gbk') as f:
        for i in f:
            a = i.replace(':', ' ').strip()
            b = a.split(' ')
            dic = dict([(b[0], b[1]), (b[2], int(b[3])), (b[4],int(b[5]))])
            print(dic)
    low way
    l1 = []
    with open('a1.txt',encoding='utf-8') as f1:
        for i in f1:
            li = i.strip().split()
            dic = {}
            for j in li:
                l2 = j.strip().split(':')
                dic[l2[0]] = l2[1]
            l1.append(dic)
    print(l1)
    老师方法

    文件a2.txt内容:每一行内容分别为商品名字,价钱,个数。

    文件内容:
    序号     部门      人数      平均年龄      备注
    1       python    30         26         单身狗
    2       Linux     26         30         没对象
    3       运营部     20         24         女生多
    通过代码,将其构建成这种数据类型:
    [{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'},
    ......]

    d = []
    with open('a2.txt', mode='r', encoding='gbk')as f:
        s = f.readline()
        data = s.strip().split(' ')
        b = [x for x in data if x != '']
        for i in f:
            data1 = i.strip().split(' ')
            c = [x for x in data1 if x != '']
            dic = dict([(b[0], int(c[0])), (b[1], c[1]), (b[2], int(c[2])), (b[3], int(c[3])), (b[4], c[4])])
            d.append(dic)
    print(d)
    my idea
    d = []
    with open('a2.txt', mode='r', encoding='gbk')as f:
        lis = f.readline().strip().split()
        for i in f:
            b = i.strip().split()
            dic = dict([(lis[0], b[0]),(lis[1], b[1]),(lis[2], b[2]),(lis[3], b[3]),(lis[4], b[4])])
            d.append(dic)
    print(d)
    改造后的,看看和上面哪里不同了
    lis = []
    with open('message.txt',encoding='gbk') as f:
        lis1 = f.readline().strip().split(',')
        for j in f:
            dic = {}
            lis2 = j.strip().split(',')
            for i in range(len(lis1)):
                dic[lis1[i]] = lis2[i]
            lis.append(dic)
        print(lis)
    自己为啥想不到,利用len的方法
  • 相关阅读:
    Nodejs与ES6系列3:generator对象
    Nodejs与ES6系列2:Promise对象
    Nodejs与ES6系列1:变量声明
    Nodejs与ES6系列4:ES6中的类
    angular单元测试与自动化UI测试实践
    javascript 异步模块加载 简易实现
    javascript模式 (3)——工厂模式和装饰模式
    TP手册学习第四内置天
    TP手册学习第三天
    tp5命令行基础
  • 原文地址:https://www.cnblogs.com/LearningOnline/p/8448578.html
Copyright © 2020-2023  润新知