• 写给小白的Python之013:文件操作


     

    一、文件的打开与关闭

    1. 文件的打开

    在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。

    open(文件名,访问模式)

    示例如下:
    f = open('test.txt', 'w')

    2. 文件的关闭

    示例如下:

    # 新建一个文件,文件名为:test.txt
    f = open('test.txt', 'w')
    
    # 关闭这个文件
    f.close()

    注意:文件打开,执行必要的操作后必须要关闭。

    但是我们总是经常忘记关闭它,怎么办呢?

    3. 文件的另一种打开方式

    with open(文件名, 访问模式) as 别名:
        pass  # 对文件执行的操作

    上述方法和以下代码是等价的:

    别名 = open(文件名, 访问模式)
    pass
    别名.close()

    由此可知,使用with方法访问文件,就不必在手动close它,Python会自动把文件关闭掉,是不是很贴心?

    二、文件的读写

    1. 写数据(write)

    使用write()可以完成向文件写入数据。
    demo:

    # 新建一个文件 file_write_test.py,向其中写入如下代码:
    f = open('test.txt', 'w')
    f.write('hello world, i am here!')
    f.close()
    # 运行之后会在file_write_test.py文件所在的路径中创建一个文件test.txt,其中数据如下:
    hello world, i am here!

    注意:
    如果文件不存在那么创建,如果存在那么就先清空,然后写入数据。

    2. 读数据(read)

    使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
    num大于数据长度时,不会报错。读完后,再读的话,会得到''空字符串。
    demo:

    # 新建一个文件file_read_test.py,向其中写入如下代码:
    f = open('test.txt', 'r')
    content = f.read(5) # 最多读取5个数据
    print(content)
    print("-"*30) # 分割线,用来测试
    content = f.read() # 从上次读取的位置继续读取剩下的所有的数据
    print(content)
    f.close() # 关闭文件,这个是个好习惯哦
    
    # 运行现象:
    hello
    ------------------------------
    world, i am here!

    注意:
    如果用open打开文件时,如果使用的"r",那么可以省略,即只写 open('test.txt')

    3. 读数据(readlines)

    就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
    读完后,再读的话,会得到[]空列表。

    demo:

    #coding=utf-8
    f = open('test.txt', 'r')
    content = f.readlines()
    print(type(content))
    
    i=1
    for temp in content:
        print("%d:%s" % (i, temp))
        i += 1
    
    f.close()
    
    运行现象:
    <class 'list'>
    1:hello world, i am here!

    <4>读数据(readline)

    一次读一行。读完后,再读的话,会得到''空字符串。

    #coding=utf-8
    f = open('test.txt', 'r')
    
    content = f.readline()
    print("1:%s" % content)
    
    content = f.readline()
    print("2:%s" % content)
    
    f.close()
    
    运行现象:
    1:hello world, i am here!
    2:hello world, i am here!

    想一想:
    如果一个文件很大,比如5G,试想应该怎样把文件的数据读取到内存然后进行处理呢?

    案例:制作文件的备份

    任务描述:输入文件的名字,然后程序自动完成对文件进行备份。

    参考代码:

    # 获取文件名
    src_name = input('请输入要备份的文件名:')
    
    # 漂亮的目标文件名 aaa.bbb.txt
    index = src_name.rfind('.')
    dest_name = src_name[:index]+'[复件]' + src_name[index:]
    
    # 打开文件
    src_file = open(src_name, 'rb')
    dest_file = open(dest_name, 'wb')
    
    # 复制文件内容
    while True:
        content = src_file.read(1024*8)   # 1024表示1024个字节
        if len(content) == 0:
            break
    
    dest_file.write(content)
    
    # 关闭文件
    src_file.close()
    dest_file.close()

    为什么使用src_file.read(1024*8),而不是src_file.read()呢?因为如果文件很大的话,使用read()读取会把内存撑爆。这时候使用以1024字节单位循环读取的话,就可以读取大文件了。

    三、文件的相关操作

    有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能。
    1. 文件重命名

    os模块中的rename()可以完成对文件的重命名操作。
    rename(需要修改的文件名, 新的文件名)
    import os
    os.rename("毕业论文.txt", "毕业论文-最终版.txt")

    2. 删除文件
    os模块中的remove()可以完成对文件的删除操作。
    remove(待删除的文件名)
    import os
    os.remove("毕业论文.txt")

    3. 创建文件夹
    import os
    os.mkdir("张三")

    4. 删除文件夹
    import os
    os.rmdir("张三")

    5. 获取当前目录
    import os
    os.getcwd()

    6. 改变默认目录
    import os
    os.chdir("../")

    7. 获取目录列表
    import os
    os.listdir("./")

    案例:批量修改文件名

    需求:批量在文件名前加前缀

    参考代码:

    #coding=utf-8
    # 批量在文件名前加前缀
    import os
    funFlag = 1 # 1表示添加标志 2表示删除标志
    folderName = './renameDir/'
    
    # 获取指定路径的所有文件名字
    dirList = os.listdir(folderName)
    
    # 遍历输出所有文件名字
    for name in dirList:
        print(name)
    
        if funFlag == 1:
            newName = '[孟德出品]-' + name
        elif funFlag == 2:
            num = len('[孟德出品]-')
            newName = name[num:]
    print(newName)
    
    os.rename(folderName+name, folderName+newName)
    View Code

    四、编码转换

    str->bytes:encode编码
    bytes->str:decode解码
    字符串通过编码成为字节码,字节码通过解码成为字符串。

    >>> text = '我是文本'
    >>> text
    '我是文本'
    >>> print(text)
    我是文本
    >>> bytesText = text.encode()
    >>> bytesText
    b'xe6x88x91xe6x98xafxe6x96x87xe6x9cxac'
    >>> print(bytesText)
    b'xe6x88x91xe6x98xafxe6x96x87xe6x9cxac'
    >>> type(text)
    <class 'str'>
    >>> type(bytesText)
    <class 'bytes'>
    >>> textDecode = bytesText.decode()
    >>> textDecode
    '我是文本'
    >>> print(textDecode)
    我是文本

    其中decode()与encode()方法可以接受参数,其声明分别为:

    bytes.decode(encoding="utf-8", errors="strict")
    str.encode(encoding="utf-8", errors="strict")

    其中的encoding是指在解码编码过程中使用的编码(此处指“编码方案”是名词),errors是指错误的处理方案。
    errors有两个选项:

    strict 表示严格按照指定的格式进行编码解码,如果编码解码不成功,则程序崩溃。
    ignore 表示忽略编码解码不成功的字符,这样代码不会崩溃。

    详细的可以参照官方文档:
    str.encode()
    bytes.decode()

    五、综合应用:学生管理系统 (文件版)

     需求就不说了,先把代码运行一遍,看看效果,然后自己写一个。

      1 import time
      2 import os
      3  
      4 # 定一个列表,用来存储所有的学生信息(每个学生是一个字典)
      5 info_list = []
      6  
      7  
      8 def print_menu():
      9     print("---------------------------")
     10     print("      学生管理系统 V1.0")
     11     print(" 1:添加学生")
     12     print(" 2:删除学生")
     13     print(" 3:修改学生")
     14     print(" 4:查询学生")
     15     print(" 5:显示所有学生")
     16     print(" 6:保存数据")
     17     print(" 7:退出系统")
     18     print("---------------------------")
     19  
     20  
     21 def add_new_info():
     22     """添加学生信息"""
     23     global info_list
     24  
     25     new_name = input("请输入姓名:")
     26     new_tel = input("请输入手机号:")
     27     new_qq = input("请输入QQ:")
     28  
     29     for temp_info in info_list:
     30         if temp_info['name'] == new_name:
     31             print("此用户名已经被占用,请重新输入")
     32             return  # 如果一个函数只有return就相当于让函数结束,没有返回值
     33  
     34     # 定义一个字典,用来存储用户的学生信息(这是一个字典)
     35     info = {}
     36  
     37     # 向字典中添加数据
     38     info["name"] = new_name
     39     info["tel"] = new_tel
     40     info["qq"] = new_qq
     41  
     42     # 向列表中添加这个字典
     43     info_list.append(info)
     44  
     45  
     46 def del_info():
     47     """删除学生信息"""
     48     global info_list
     49  
     50     del_num = int(input("请输入要删除的序号:"))
     51     if 0 <= del_num < len(info_list):
     52         del_flag = input("你确定要删除么?yes or no")
     53         if del_flag == "yes":
     54             del info_list[del_num]
     55     else:
     56         print("输入序号有误,请重新输入")
     57  
     58  
     59 def modify_info():
     60     """修改学生信息"""
     61     global info_list
     62  
     63     modify_num = int(input("请输入要修改的序号:"))
     64     if 0 <= modify_num < len(info_list):
     65         print("你要修改的信息是:")
     66         print("name:%s, tel:%s, QQ:%s" % (info_list[modify_num]['name'],
     67             info_list[modify_num]['tel'],info_list[modify_num]['qq']))
     68         info_list[modify_num]['name'] = input("请输入新的姓名:")
     69         info_list[modify_num]['tel'] = input("请输入新的手机号:")
     70         info_list[modify_num]['qq'] = input("请输入新QQ:")
     71     else:
     72         print("输入序号有误,请重新输入")
     73  
     74  
     75 def search_info():
     76     """查询学生信息"""
     77     search_name = input("请输入要查询的学生姓名:")
     78     for temp_info in info_list:
     79         if temp_info['name'] == search_name:
     80             print("查询到的信息如下:")
     81             print("name:%s, tel:%s, QQ:%s" % (temp_info['name'],
     82                 temp_info['tel'], temp_info['qq']))
     83             break
     84     else:
     85         print("没有您要找的信息....")
     86  
     87  
     88 def print_all_info():
     89     """遍历学生信息"""
     90     print("序号	姓名		手机号		QQ")
     91     i = 0
     92     for temp in info_list:
     93         # temp是一个字典
     94         print("%d	%s		%s		%s" % (i, temp['name'], temp['tel'], temp['qq']))
     95         i += 1
     96  
     97  
     98 def save_data():
     99     """加载之前存储的数据"""
    100     f = open("info_data.data", "w")
    101     f.write(str(info_list))
    102     f.close()
    103  
    104  
    105 def load_data():
    106     """加载之前存储的数据"""
    107     global info_list
    108     f = open("info_data.data")
    109     content = f.read()
    110     info_list = eval(content)
    111     f.close()
    112  
    113 def main():
    114     """用来控制整个流程"""
    115  
    116     # 加载数据(1次即可)
    117     load_data()
    118  
    119     while True:
    120         # 1. 打印功能
    121         print_menu()
    122  
    123         # 2. 获取用户的选择
    124         num = input("请输入要进行的操作(数字):")
    125  
    126         # 3. 根据用户选择,做相应的事情
    127         if num == "1":
    128             # 添加学生
    129             add_new_info()
    130         elif num == "2":
    131             # 删除学生
    132             del_info()
    133         elif num == "3":
    134             # 修改学生
    135             modify_info()
    136         elif num == "4":
    137             # 查询学生
    138             search_info()
    139         elif num == "5":
    140             # 遍历所有的信息
    141             print_all_info()
    142         elif num == "6":
    143             # 保存数据到文件中
    144             save_data()
    145         elif num == "7":
    146             # 退出系统
    147             exit_flag = input("亲,你确定要退出么?~~~~(>_<)~~~~(yes or no) ")
    148             if exit_flag == "yes":
    149                 break
    150         else:
    151             print("输入有误,请重新输入......")
    152  
    153  
    154         input("
    
    
    按回车键继续....")
    155         os.system("clear")  # 调用Linux命令clear完成清屏
    156  
    157 # 程序的开始
    158 main()
    159  
    160 注意:
    161 以上程序,在运行之前请先建立info_data.data文件,并且写入一对中括号[]即可
    162 等到后面讲解完异常之后就解决了这个问题
    163  
    View Code
  • 相关阅读:
    温昱谈架构和框架(Framework)的区别
    温故而知新:HttpApplication,HttpModule,HttpContext及Asp.Net页生命周期
    怎么设计一个好的数据库
    ORACLE修改表空间方法
    为[ double ] 类型 添加[zzzzz]方法
    常用的html代码 加粗 加亮 字型加大 变色等
    ASP.NET页面级别的事务
    无法加载 DLL“oramts.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
    把漫画浏览器的离线下载的功能给实现了一下
    以前写的IE9鼠标手势插件在IE10下也能工作
  • 原文地址:https://www.cnblogs.com/salmond/p/8926054.html
Copyright © 2020-2023  润新知