Fork me on GitHub

day-09

1. 文件处理

  • 什么是文件

    操作系统提供的虚拟概念,存储信息(用二进制存储)

  • 什么是文件处理

    修改存储的信息

  • 文件的绝对路径和相对路径

    • 文件的路径:文件在硬盘的地址
    • 绝对路径:从盘符开始的路径: D:\Program Files\python\test.py
    • 相对路径:执行文件(当前运行的文件)的文件夹下的文件名,执行文件和打开文件属于同一文件夹下: test.py

    项目中尽量用相对路径。

  • 操作文件的流程

    1. 打开文件

      • 找到文件所在的路径
      • 选择打开的模式
      • 指定字符编码
      f = open('test.py','r',encoding='utf-8')	# 以‘r’模式,‘utf-8’格式,打开当前文件夹下的‘test.py’
      
    2. 读取 或 修改文件

      data = f.read()	# 读取文件内的内容给到对象 data
      
    3. 保存文件

      f.flush()	# 快速保存,可以不使用
      
    4. 关闭文件

      f.close() # 告诉操作系统关闭文件
      

2. 文件的三种打开模式和两种方式

  1. 文件的三种打开模式
  • 读取: rt :读文本内容,只读

    f = open('test.py','r',encoding='utf-8')
    data = f.read()	# 读取所有文本内容
    print(f.readable()) # 判断是否可读
    print(f.writable()) # 判断是否可写
    
    

    运行结果:

    True
    False
    
    Process finished with exit code 0
    
    • 了解

      print(f.readline())  # 一行一行读取
      print(f.readlines())  # 读取所有行放入列表
      
    • 循环读出文本内容

      for i in f.read():  # 循环出一个个字符
      	print(i)
      
      for i in f:  # 循环出一行行的内容 --->这种方式更节省内存
      	print(i)
      
  • 只写: wt :打开文件后先清空文本内容,再写入新的内容

    f = open('test.py','w',encoding='utf-8')
    print(f.readable()) # 判断是否可读
    print(f.writable()) # 判断是否可写
    

    运行结果:

    False
    True
    
    Process finished with exit code 0
    
    • 了解

      f.writelines(['abc', 'def', 'ghi'])  # 自动拼接列表元素,一行写入
      

      文件内保存为:

      abcdefghi
      
  • 只写: at :只写,在文件原内容最后面写入新的内容

    f = open(r'D:\上海python12期视频\python12期视频\day 09\test.py', 'at', encoding='utf8')
    print(f.readable())
    print(f.writable())
    

    运行结果:

    False
    True
    
    Process finished with exit code 0
    

    使用 w a 模式可以自动创建一个新的文件,使用 r 模式时,文件必须是已经存在的。

  1. 文件的两种打开方式

    两种方式都不单独使用,一般与r/w/a联用

  • 文本方式: t :打开文本,需要指定字符编码

    指定打开的文本文件的模式为 rt 或 wt 或 at ,一般可以省略 t 直接写作 r 或 w 或 a

  • 二进制方式: b :一般用于音频/视频/图片的保存

    指定打开的文本文件的模式为 rb 或 wb 或 ab

3. with 管理文件上下文

由于每次保存文件后,都需要手动将文件关闭掉,解除对操作系统的占用,比较麻烦,所以python中提供了一种可以自动关闭文件的方法。

  • 语法:

    with open('test.py', 'r', encoding='utf8') as f:
        # print(f.read())
        # 在这个缩进下不会关闭文件,在这个缩进下对文件操作
        data = f.read()  # data放到python的内存中
    print(data) # 关闭文件(操作系统),但没有关闭python内存中的文件
    print(f.read())  # 由于不在缩进内,操作系统的文件已经关闭,报错
    

4. 文件的高级应用(了解)

1.三种新的文件打开模式(使文件即可读又可写),尽量不要使用。

当一个文件即可读又可写的时候,由于读取和写入的时间差,可能出现写入和读取的错误,无法正确的读取到或者写入我们想要的信息。

  • 可写可读: r+

    with open('test.py', 'r+', encoding='utf8') as fr:
        print(fr.readable())
        print(fr.writable())
        fr.write('写入内容')  # 光标在文件头部,会覆盖后面的字符
    

    运行结果:

    True
    True
    
    Process finished with exit code 0
    
  • 可写可读: w+w+ w 没有任何区别

    with open('test.py', 'w+', encoding='utf8') as fw:
        print(fw.readable())
        print(fw.writable())
    

    运行结果:

    True
    True
    
    Process finished with exit code 0
    
  • 可写可读: a+ :a模式默认光标在尾部

    with open('test.py','a+',encoding='utf8') as fa:
    	print(fa.readable())
        print(fa.writable())
        fa.seek(0,0)	# 由于 a 模式打开文件,默认光标在尾部,所以想要读取文件内容必须将光标移动到文件头
        print(fa.read())
    

    运行结果:

    True
    True
    
    Process finished with exit code 0
    

    综上,如果某些场景真的需要文件可读又可写,应该用两种不同的模式打开两次文件

2.光标的高级应用(移动文件内的光标)

  • 字节:8个二进制位为一个字节(以下方法都是以字节为单位)

    • seek() :移动光标

      with open('test.py', 'rb') as fr:
          fr.seek(3)  # 打开文件后,将光标往后移动3个字节(一个中文),默认从开头开始读取
          # 如果 seek 移动的字符不够 3 个字节,或刚好将汉字的三个字节切分,则会导致乱码
          # whence 参数:规定只有0,1,2 三种模式
          fr.seek(3, 0)  # 0 表示从开头往后移动 3 个字符,默认为 0 ,可以不写
          fr.seek(3, 1)  # 1 表示从中间往后移动 3 个字符
          fr.seek(3, 2)  # 2 表示从开头往后移动 3 个字符
          print(fr.read())
          print(fr.read().decode('utf8'))
      
    • tell() :告诉当前光标所在的位置

      with open('test.py', 'rb') as fr:
          fr.seek(3, 0)
          print(fr.tell())	# 从文件开头到当前指针所在位置
      

      运行结果:

      3
      
      Process finished with exit code 0
      
    • truncate() :截断

      with open('test.py', 'ab') as fa:	
          fa.truncate(2)	#截断2个字节后的所有字符,如果3个字节一个字符,只能截断2/3个字符,还会遗留1/3个字符,会造成乱码
      
  • 字符:3个字节对应一个字符(中文)

    • read() :以字符为单位,移动光标

      with open('test.py', 'r', encoding='utf8') as fr:
          print(fr.read(3))  # 3 表示 3 个字符,不加默认读取所有
      # 中文和英文都属于一个字符
      

5. 文件的修改

文件没有修改的说法,只有覆盖。

缓存文件的原理:

import os

# 同时打开多个文件
with open('test.py', 'r', encoding='utf-8') as fr, \
        open('test_swap.py', 'w', encoding='utf-8') as fw:
    data = fr.read()
    data = data.replace('原内容', '修改的内容') # 在新文件里用修改的内容替换掉原来的内容

    fw.write(data)
    
os.remove('test.py')	# 删除原文件
os.rename('test_swap.py', 'test.py')	# 将新的文件重命名为旧文件

但是这样当文件很大的时候,影响效率,下面是改进:

import os

# 同时打开多个文件
with open('test.py', 'r', encoding='utf8') as fr, \
        open('test_swap.py', 'w', encoding='utf8') as fw:
    # 逐行修改保存,再大的文件都能修改
    for i in fr:
        s = '新的内容'
        i = i.replace('原内容', s)
        fw.write(i)
        # fw.flush()  # 先保存成功再继续运行

os.remove('test.py')	# 删除原文件
os.rename('test_swap.py', 'test.py')	# 将新的文件重命名为旧文件

6. 登录注册

  • 注册功能:

    • 实现代码:

      # 注册
      count = 0
      while count < 3:
          username_inp = input('请输入你的用户名:')
          pwd_inp = input('请输入你的密码:')
          re_pwd_inp = input('请在此输入你的密码:')
      
          if not pwd_inp == re_pwd_inp:
              print('两次密码输入不一致')
              count += 1
              continue
      
          with open('user_info.txt', 'a', encoding='utf8') as fa:
              fa.write(f'{username_inp}:{pwd_inp}\n')  # :表示用户名和密码的分割;|用户和用户之间的分割
              fa.flush()
              break
      
  • 登录功能:

    • 实现代码:

      # 登录
      username_inp = input('请输入你的用户名:')
      pwd_inp = input('请输入你的密码:')
      
      with open('user_info.txt', 'r', encoding='utf8') as fr:
          for user_info in fr:
              username, pwd = user_info.split(':')
      
              if username.strip() == username_inp and pwd.strip() == pwd_inp:  # strip可以去掉两端的换行符
                  print('登录成功')
                  break
          else:
              print('登录失败')
      
posted @ 2019-09-18 19:37  Yugaliii  阅读(87)  评论(0编辑  收藏  举报