python15 文件操作

python 15 文件操作

一、计算机存储

  • 默认情况下程序中的数据是保存在运行内存中的,当程序运行结束,在运行内存中保存的数据会自动销毁。
  • 如果希望在这次运行程序的时候,可以使用上一次程序产生的数据,就必须把数据保存在硬盘(磁盘)中。
  • 硬盘保存数据的最小单位是文件。

二、数据持久化

  1. 怎么将程序中的数据保存到文件中?
  2. 怎么在程序中获取文件中的内容?

​ 答案:文件操作

三、文件操作

基本流程:打开文件—>文件读写操作—>关闭文件

1. 打开文件

语法:open(file,mode=‘r’,*,encoding=None)--------以指定的方式打开指定文件,返回一个文件的对象

1)参数1 --------- file :需要打开的文件路径(文件路径可以写绝对路径,也可以写相对路径)
  • 绝对路径:文件在计算机中的全路径(windows从盘开始写的路径)

  • 相对路径:在写文件路径的时候可以用 ‘.’ 和 ‘…’ ,‘.‘开头代表当前打开的文档所在文件,’…’ 开头代表当前打开的文档(文件)所在的文件夹的上级目录。(当前目录指的是当前代码文件所在的文件夹)

  • 注意:如果使用相对路径,被打开的文件必须放在工程中;
    如路径是以 ‘. / ’ 开头的,’ . / ’ 可以省略

  • 案例:

    open('./file/abc.txt')
    open('./test.txt')
    
2)参数2-------mode :文件的打开方式,用来决定打开文件之后能做什么(能读还是能写)、操作文件的时候,数据对应的类型(是字符串还是二进制)
  • 给mode赋值的时候需要两组值:

  • 第一组:决定打开后能做什么对应的值

    • r : 只读-------打开不存在的文件,会报错。
    • w : 只写-------打开的时候,会先清空文件里面的内容,打开不存在的文件不会报错,并且会自动创建文件。
    • a : 只写--------打开的时候,不会清空原文件内容,打开不存在的文件不会报错,并且会自动创建文件。
  • 第二组: 决定操作的文件的时候,数据的类型二选一,如果不选,就会默认选择 t 。

    • t : 字符串
    • b : 二进制(bytes)(图片数据音频是下载成二进制的)
  • 赋值的时候,上面的两组值都必须选择一个(如果第二组值不选,就相当于选的是t )

    • rt (tr) 、rb (br)、r、wt、wb、w、ab、at、a
  • 案例说明

    • 说明r只是读操作
    f=open('./files/abc','r',encoding='utf-8')  #拿到文件后,是一个对象,用一个变量名来命名。
    f.read()  #可以读
    f.write('本地词语')   #报错io.UnsupportedOperation: not writable,不支持写
    
    • 说明w只是写,会清空原文件

      f=open('./files/abc','w')
      f.write('sdfgh')  #清空了原文件的内容,然后加上了’sdfgh‘
      f.read()      #报错,只能清空写不能读  io.UnsupportedOperation: not readable
      
    • 说明a只是写,不会清空原文件

      f=open('./files/abc','a')   #k可以运行,不会报错,打开的文件里面的内容也在,没有清空
      f.write('++++====cidbciyvc')     #正常运行,加上了添加的内容sdfghcidbciyvc++++====cidbciyvc
      f.read()     # 报错,不可读,只能写io.UnsupportedOperation: not readable
      
    • 说明 t 对应的类型是字符串

      f=open('./files/abc','r')  #拿到文件
      result=f.read()             #把读到的结果记为result
      print(type(result))         ## <class 'str'> 输出的读到的数据的类型是字符串类型
      
      f=open('./files/abc','rt')  #拿到文件
      result=f.read()             #把读到的结果记为result
      print(type(result))          # <class 'str'> 输出的读到的数据的类型是字符串类型
      
      f=open('./files/abc','rb')  #拿到文件
      result=f.read()             #把读到的结果记为result
      print(type(result))         #<class 'bytes'> 输出读到的数据的类型是二进制,pdf,图片、音频存储方式是二进制
      
      f=open('./files/abc','wb')  #拿到文件
      result=f.write('01')             #把读到的结果记为result
      print(type(result))    #TypeError: a bytes-like object is required, not 'str'
      
    • 说明t对应的类型是二进制

      f=open('./files/abc','at')  # 拿到文件
      result=f.write('00000001')        # 把读到的结果记为result
      print(type(result))
      print(result)
      
    • 尝试打开不存在的文件

      =open('./files/fc.py','w')
      f.read()   #报错,文件不存在[Errno 2] No such file or directory: './practice.py/abc'
      f.write('gdigy')   # 会创建一个fc.py文件,这个在新文件里保存
      
      g=open('./files/wer.txt','a')
      g.write('gcdiudi')     #会创建一个wer.txt文件,这个在新文件里保存
      
3) 参数3--------encoding : 文本文件编码方式(只有在以t方式打开文件的时候,才需要encoding)
  • 一般赋值为’utf-8’ 、‘gbk’ 也是一种常见的文件编码方式。windows的一些文本保存的编码格式是 ’ gbk ’

  • utf-8 : 文本数据在存储的时候,ascii码表中的符号用1个字节来存储,一个中文用三个字符来存储,可以对任何符号编码。

  • gbk : 文本数据在存储的时候,ascii码表中的符号用一个字节来存储,一个中文用2个字节来存储,除了ascii码表和中文外,不能对其他符号进行编码。

  • 注意:乱码并没有说明数据有误,而是打开方式不对。

  • 使用编码值的原则:存储数据的时候,使用编码值要和获取数据的时候,对应的编码值不一致。如果不设置,会默认是计算机的编码方式。

  • 案例说明

    f=open('./files/abc','w',encoding='utf-8')
    f.write('sgc你好')
    
    f=open('./files/abc','r',encoding='gbk')
    result=f.read()
    print(result)   #sgc浣犲ソ编码值错误
    #改正
    f=open('./files/abc','r',encoding='utf-8')
    result=f.read()
    print(result)  #sgc你好
    
    • 如果输入的内容是全是字母,这两个编码方式都是同一个字符,所有没有影响。
2. 文件读写
1)文件读操作
  • 语法1:文件 . read( ) ------获取整个文件的内容。

    • 从读写位置开始,读到文件结束,读写位置默认在文件开头,随着读操作的进行(不管是read还是Readline),读写位置不断在改变。
  • 语法2:文件 . readline( ) ------获取一行内容(只能文本文件有效)。

  • 从读写位置开始至一行结束。

  • 语法3:文件 . readlines( ) ------获取整个文件内容,返回一个列表,列表中的每个元素是每一行内容(只能文本有效)

  • 案例操作:

    #=============文件读操作===============
    f=open('files/student.txt',encoding='utf-8')
    result=f.read()
    print(result)
    ##结果显示
    # 鹅鹅鹅
    # 曲项向天歌
    # 白毛浮绿水
    # 红掌拨清波
    #=============readline ----读一行操作============
    f=open('files/student.txt',encoding='utf-8')
    result=f.readline()
    print(result)   #鹅鹅鹅
    print('----------------------------冷静的分割线-------------------------------')
    #再读一行内容
    result=f.readline()
    print(result)
    print('----------------------------冷静的分割线-------------------------------')
    #再次使用read来读文件
    result=f.read()    #前两次读的时候,光标停留在第三行的开头,所以,read读的时候,会继续在前面光标结束的位置开始,读完所有内容。
    print(result)
    #结果显示
    #白毛浮绿水
    #红掌拨清波
    
  • 注意:如果不想接着前面读到的位置开始读,想要一次性读写完所有的文件内容。

    • 方法1.就直接重新打开文件,然后一次性读完

    • 方法2;设置读写位置,f . seek(0) ,这条语句将读写位置移动到文件开头。

    • 案例演示

      f=open('./files/student.txt','r',encoding='utf-8')
      result=f.readline()
      print(result)   #鹅鹅鹅
      #此时光标已经停在了第二行的开头,但是想从头开始读,就用seek(0)
      f.seek(0)    #让读写位置移动到文件开头
      result=f.readline()   #这个时候,还是读读的是鹅鹅鹅
      print(result)   #鹅鹅鹅
      print('----------------------------冷静的分割线-------------------------------')
      f.seek(0)
      result=f.read()
      print(result)
      #读取内容  读到整个文件
      # 鹅鹅鹅
      # 曲项向天歌
      # 白毛浮绿水
      # 红掌拨清波
      
      #————————————————————readlines --读一行操作,列表返回操作——————————————————————
      f.seek(0)   #因为前面的程序已经打开过f,不需要重新在打开文件,就直接使用seek(0),让光标移到开始的位置
      result=f.readlines()
      print(result)
      #['鹅鹅鹅\n', '曲项向天歌\n', '白毛浮绿水\n', '红掌拨清波']  #返回值是以列表的形式返回,\n是换行,不想要可以采用切片去掉
      print('----------------------------冷静的分割线-------------------------------')
      
2)文件写操作
  • 语法1: 文件对象.write(数据)

  • 语法2:文件对象 . writeline (数据)

    写的时候,是以列表的形式输入进去。

  • 注意:写的时候,如果选择w只会在第一次清空,后面多次选择w, b。不会多次选择w 不会清空,会继续添加新的内容进去。

    • 案例演示

      #============写操作======================= ’a‘是在后面继续添加内容,’w‘是清空之后再添加内容,所有要考虑好哪一种
      f=open('./files/student.txt','a',encoding='utf-8')
      # result=f.write('\n只识弯弓射大雕,看同学少年,风华正茂')  #\n表示换行添加,不写的话就是再原来光标的位置继续添加内容
      # print(result)
      '''
      结果显示
      鹅鹅鹅
      曲项向天歌
      白毛浮绿水
      红掌拨清波
      只识弯弓射大雕,看同学少年,风华正茂
      '''
      f=open('./files/student.txt','w',encoding='utf-8')
      result=f.write('***鹅鹅鹅,\n曲项向天歌,\n白毛浮绿水,\n红掌拨清波')   ###\n表示换行添加,不写的话就是再原来光标的位置继续添加内容
      result2=f.write('一代天骄,\n成吉思汗,\n只识弯弓射大雕,\n北国风光,千里冰封,万里雪飘,\n望长城内外,惟余莽莽,\n大河上下,顿失滔滔,\n山舞银蛇,原驰蜡象,\n欲与天公试比高')
      '''
      结果显示
      ***鹅鹅鹅,
      曲项向天歌,
      白毛浮绿水,
      红掌拨清波一代天骄,
      成吉思汗,
      只识弯弓射大雕,
      北国风光,千里冰封,万里雪飘,
      望长城内外,惟余莽莽,
      大河上下,顿失滔滔,
      山舞银蛇,原驰蜡象,
      欲与天公试比高
      
      '''
      
3. 关闭文件
  • 语法:文件对象. close ( )

  • 注意:关闭文件后,就无法操作,想要继续操作,就必须再把程序打开;为了安全起见,及时关闭。第二个,减少运行内存的占用。

  • 案例演示

    f.close()
    f.write('nxxxxxx')   #关闭之后,运行文件,就会报错,ValueError: I/O operation on closed file.
    

四、文件操作的应用

数据持久化步骤:

  • 第一步:确定需要持久化的数据
  • 第二步:创建需要持久化数据的文件
  • 第三步:确定文件初始内容(就是需要持久化的数据初始值)
  • 第四步:在程序中需要这个数据的时候从文件中获取这个数据。
  • 第五步:程序中如果修改数据以后,必须将最新的数据写到文件中。
#案例:写程序打印程序运行次数
#确定需要持久化的数据     -   运行次数
f=open('./runcount','r',encoding='utf-8')   #打开已经创建好的持久化的数据
count=int(f.read())   #读到runcount的文本内容,因为是文本,所有要数据转换成int,
f.close()             #关闭文件

count += 1               #运行次数+1
print(count)          #打印运行次数

f=open('./runcount','w',encoding='utf-8')        # 再次打开持久化文件
f.write(str(count))                                 # 将新的运行次数保存在持久化数据中
f.close()                        #关闭文件
  • 练习:

    
    #练习:提示用户输入名字添加学生,添加完后打印已经添加过的所有的学生名字
    #1)确定需要持久化的数据   -   已经添加过的所有学生的名字
    
    name=input('请输入你的名字')
    
    
    f=open('./practice.txt','at',encoding='utf-8')   #先添加名字
    f.write(input('请输入姓名:')+'  ')
    f.close()
    
    f=open('./practice.txt','r',encoding='utf-8')    #再读
    a=f.read()
    f.close()
    print(a)
    ##上述方法先写再读
    ##下述方法要先读再写
    name=input('请输入姓名:')
    f=open('./practice.txt','r',encoding='utf-8')   #先读
    added_name=f.read() + name
    print(added_name)
    
    f=open('./practice.txt','w',encoding='utf-8')    #再写
    f.write(added_name+'  ')
    
    # 请输入姓名:小红
    # 小明  小兰  小红
    f=open('./practice.txt','at',encoding='utf-8')
    f.write(a)
    f.close()
    

今日练习

设置登录注册界面
def get_all_user_name():
    """获取账号文件内容,并且将文件内容转换成字典"""
    f=open('./practice/user_name.txt','rt',encoding='utf-8')
    all_user= {}
    for x in f.readlines(): #对取出来的列表进行遍历,列表中的每个元素都是字符串(即是用户名:密码)
        name,pwsd = x .strip().split(':')   #对列表的每个元素进行切割,返回的是被切割出来的每一段字符串组成的列表
        all_user[name]=pwsd
    f.close()
    return all_user

def register():
    # 1. 输入账号和密码
    print('--------正在注册---------')
    name = input('请输入账号(不能包含分号):')
    pswd = input('请输入账号密码(不能包含分号):')
    if ';' in name or ';' in pswd:
        print('注册失败,账号不合法')
        return #函数返回
    # 2. 判断登录是否成功
    # # 1)账号是否已经注册
    all_user=get_all_user_name()
    if name in all_user:
        print('账号已经注册')
        return
    f=open('./practice/user_name.txt','at',encoding='utf-8')
    f.write(f'{name}:{pswd}\n')
    print('注册成功')


def login():
    print('--------正在登录----------')
    user_name=input('请输入账号:')
    pswd=input('请输入密码:')
    # 2. 判断登录是否成功
    # 1)账号是否已经注册
    all_user=get_all_user_name()
    if user_name not in all_user:
        print('该账号不存在,登录失败')
        return
    #2)密码是否正确
    if  all_user[user_name] != pswd:
        print('密码错误')
    else:
        print('登录成功')


def welcom():
    print('*********欢迎来到快乐星球**********')
    print(f' 1. 登录\n\n\n 2. 注册')

    print('********************************')
    value=input('输入选项')
    if value == '1':
        login()
    elif value == '2':
        register()
    else:
        print('输入有误')

if __name__=='__main__':
    welcom()
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值