写给Python社群的第9课:学一下文件处理,Python基础提高篇

举报
梦想橡皮擦 发表于 2023/02/20 14:53:20 2023/02/20
【摘要】 ⛳️ 文件处理从本篇博客开始,《写给 Python 社群》系列博客进入第二阶段,从各应用场景入手,为大家丰富 Python 基础知识理论栈。本篇博客学习 Python 中的文件处理,主要涉及三类文件,分别是文本文件,JSON 文件,XML 文件,这三种格式的文件也是后期工作中最常接触的三种类型。 ⛳️ 文本文件文本文件是最通用的文件存储格式,它可以持久保留和共享用户数据,在操作系统中接触最...

⛳️ 文件处理

从本篇博客开始,《写给 Python 社群》系列博客进入第二阶段,从各应用场景入手,为大家丰富 Python 基础知识理论栈。

本篇博客学习 Python 中的文件处理,主要涉及三类文件,分别是文本文件,JSON 文件,XML 文件,这三种格式的文件也是后期工作中最常接触的三种类型。

⛳️ 文本文件

文本文件是最通用的文件存储格式,它可以持久保留和共享用户数据,在操作系统中接触最多的就是 .txt 后缀的文本文件,其实 .ini.csv 也都是文本文件的常用后缀。

本篇博客以后缀为 .txt 的文件类型进行讲解。

🔥 建立文本文件

在操作系统的文件夹中,可以直接使用鼠标右键建立普通文本文件,下面看一下如何用 Python 实现相同的操作,代码如下。

filename = 'd:\demo.txt'
file = open(filename,'w')
file.close()

代码非常简单,核心用到的是 open() 函数与 close() 函数,第一个函数用来创建一个文件对象,第二个用来关闭文件对象。
open() 函数的语法格式如下:

open(file,mode='w')

参数 file 用来指定需要操作的文件名,可以使用相对路径或者绝对路径,参数 mode 设置操作文件的方式,其可选值如下所示。

  • r:只读打开文件;
  • w:只写打开文件,如果文件不存在,创建文件;
  • a:追加写入方式打开文件,文件不存在,创建文件;
  • b:二进制模式打开文件;
  • +:读写方式打开文件。

上述模式可以进行搭配使用,例如 ab,表示二进制追加模式打开文件,a+,读写追加模式打开文件,除了这些常用的模式外,还存在一些不常用的关键字,如下所示。

  • x:以可写方式新建文件;
  • t:文本模式;

这里还需要记住,open() 函数中参数 mode 的默认值是 rt,即以文本只读模式打开文件,所以前文代码如果不设置 w,仅使用 open() 函数,会出现错误,也就是上一篇博客说的异常,正好可以复习一下文件操作的异常类型为 FileNotFoundError

文件操作完毕,必须要及时关闭文件,即前文的 close() 函数。

🔥 文件基本读写

新建文件之后,就需要对文件进行后续读写操作了,本小节为大家说明一下在 Python 中重点要掌握的函数。

file.write() 写入方法。

使用 file.write(s) 可以将文本内容写入文件,其中 file 表示以可写方式打开的文件对象,s 是待写入的内容。
示例代码如下所示。

filename = 'd:\demo.txt'
file = open(filename,'w')
file.write('梦想橡皮擦') # 将字符串写入文件
file.close()

可以看到 open() 函数的 mode 设置为 w,该模式表示文件为写入模式,每次运行代码都会重新创建一个文件,如果希望在原文件进行追加,可以使用关键字 a

filename = 'd:\demo.txt'
file = open(filename,'a')
file.write('梦想橡皮擦') # 将字符串写入文件
file.close()

实战的时候可以通过循环写入多行数据,在 Windows 中换行的标志是 \r\n,也可以直接使用 \n,在 UNIX 中,一行的结束标志数 \n,在 Mac 中,一行结束的标志是 \r,这里需要特别注意一下。

file.read() 读取方法。
file.read(size) 表示读取文件内容,其 size 参数为指定读取的字节数,如果没有指定,默认读取到文件结尾。

filename = 'd:\demo.txt'
file = open(filename,'r')
ret = file.read()
print(ret)
file.close()

读取文件的时候,还可以使用 readline()readlines() 两个对象方法,分别表示读取一行和读取多行,其中 readline(size) 中可以携带一个 size 参数,如果设置了就表示返回指定大小的字节,如果未设置,则按行返回。

filename = 'd:\demo.txt'
file = open(filename,'r')
ret = file.readline()
print(ret)
file.close()

按行读取文件到一个列表中,代码和返回结果如下所示。

filename = 'd:\demo.txt'
file = open(filename,'r')
ret = file.readlines()
print(ret)
file.close()
# ['梦想橡皮擦\n', '梦想橡皮擦\n', '梦想橡皮擦\n']

在读取和写入文件的操作过程中,还存在两个函数,分别是 tell()seek(),分别表示返回当前文件可读写位置,设置当前文件读写位置。

# 返回读取位置
filename = 'd:\demo.txt'
file = open(filename,'r')
ret1 = file.readline(2)
tel = file.tell()
print(ret1)
print(tel)
file.close()

接下来通过 seek() 在指定位置插入数据,首先看一下 file.seek() 方法的原型。

file.seek(offset[,whence])

其中 offset 表示偏移量,即字节数,参数 whence 表示文件开始计算的位置,默认为 SEEK_SET,也可以用数字 0 表示,其表示通过文件开始位置+偏移量确定当前位置,设置为 SEEK_CUR(也可以设置为 1),表示从当前位置开始计算,设置为 SEEK_END (也可以设置为 2),表示从文件末尾计算。

filename = 'd:\demo.txt'
file = open(filename,'r')
file.seek(2) # 设置到第二个字节
ret1 = file.readline() # 读取当前行
print(ret1)
file.close()

也可以在指定位置插入数据,例如在第 4 个字节位置插入 @@,代码如下:

filename = 'd:\demo.txt'
file = open(filename,'a')
file.seek(4) # 设置到第4个字节
ret1 = file.write('@@')

print(ret1)

file.close()

当需要注意的是,该写入会将文件删除重新建立,即最后得到的文本文件中只包含内容 @@,如果想要在原文件内容上进行修改,需要首先将文本读取到字符串对象中,然后再对其进行编辑,重新写入到文件中才可以。

🔥 文件异常处理和文件路径

在前文已经碰到了 FileNotFoundError 类型的错误,该提示表示文件不存在,实战编码过程中还会碰到更多异常情况,所以当我们操作文件的时候,一般都需要增加 try...except 语句,进行异常捕获,语法格式如下。

try:
	# 读取文件的操作逻辑
except:
	# 异常捕获
finally:
	# 文件关闭

除了异常捕获意外,还需要对文件路径进行一下特别说明,与路径相关的模块是 os,下面介绍一些常用的方法。

获取程序运行的当前路径
该操作用到的方法是 os.path.abspath(p),该方法可以返回传入路径/文件的绝对路径,例如下述代码。

import os
p = os.path.abspath('d:/demo.txt')
print(p)

如果希望获取当前路径,可以直接传入点号(.)。

import os
p = os.path.abspath('.')
print(p)

也可以传入 os.path 对象的 curdir 属性,即下述代码。

import os
p = os.path.abspath(os.path.curdir)
print(p)

判断文件是否存在
编码过程中有时候需要根据文件是否存在,决定是否创建文件,这里就用到了 os.path.exists() 方法,该方法判断如果指定文件存在,返回 True,不存在返回 False。其衍生的两个方法也要掌握,一个是 isfile(),一个是 isdir(),分别表示判断文件和判断路径。

import os
p = os.path.isdir('G:\\78tech')
print(p)

# 检验文件代码如下
import os
p = os.path.isfile('d:/demo.txt')
print(p)

一次批量创建文件夹
在使用 open() 函数的时候,会碰到这样的情况,某路径中存在子路径(子文件夹),如果直接编写代码,会出现异常信息,例如错误的代码如下所示。

filename = 'd:/aademo/demo.txt'
file = open(filename,'w')
file.close()

这时就需要提前创建这种嵌套文件夹了,用到的方法是 os.makedirs(),示例代码如下。

import os
os.makedirs('d:/aademo/')
filename = 'd:/aademo/demo.txt'
file = open(filename,'w')
file.close()

⛳️ JSON 文件

JSON 格式文件也是项目实战中使用频率非常高的文件格式,它最早被用在 Javascript 语言中进行数据交换,后来被推广为不同程序之间数据共享的一种技术标准。

在正式学习前,需要先掌握两个核心概念,序列化和反序列化。

  • 序列化:把 Python 数据转换为 JSON 格式(一般是 JSON 格式的字符串),就叫做序列化;
  • 反序列化:相反的操作,JSON 转换为 Python 数据类型。

序列化之后的 JSON 字符串,可以存储在文件或者数据中,也可以提供过网络传输,只要大家遵循相同的标准,不同编程语言之间都可以互相解析数据。

Python 环境中内置了 JSON 数据操作模块,即 json 模块,其核心方法为 dumps()loads(),分别表示将 Python 数据转换为 JSON 字符串,和将 JSON 字符串转换为 Python 数据类型的数据,示例代码如下。

import json
my_dict = {
    "name":"梦想橡皮擦",
    "age":18,
    "sex":"girl"
}

print(my_dict)
# 将字典对象转换为JSON字符串
my_json_str = json.dumps(my_dict)
print(my_json_str)

运行代码输出如下内容。

{'name': '梦想橡皮擦', 'age': 18, 'sex': 'girl'}
{"name": "\u68a6\u60f3\u6a61\u76ae\u64e6", "age": 18, "sex": "girl"}

可以看到序列化之后的数据进行了 unicode 编码,并且由单引号变为了双引号,对比之后也可以发现 JSON 格式字符串与 Python 字典非常相近。

在上文我们使用了 dumps() 方法,你可以在测试一下 loads() 方法,即下述代码。

print(my_dict)
# 将字典对象转换为JSON字符串
my_json_str = json.dumps(my_dict)
print(my_json_str)

ret = json.loads(my_json_str)
print(ret)

除此之外,我们还可以对 JSON 文件进行读写,使用的方法是 load()dump(),注意和前文方法进行区分。

import json
my_dict = {
    "name":"梦想橡皮擦",
    "age":18,
    "sex":"girl"
}

# 以写入形式打开JSON文件
json_file = open('d:/demo.json','w')
json.dump(my_dict,json_file,ensure_ascii=False)
json_file.close()

其中可以看到 dump() 方法参数较多,说明如下:

  • 第一个参数:待写入的对象;
  • 第二个参数:文件对象;
  • ensure_ascii:默认值为 True,默认会将中文存储为 \u 格式的十六进制数据,设置为 False 时,会接收非 ASCII 类型的数据,本案例中为 GB2312 格式;

load() 方法实现从 JSON 文件读取数据,转换为 Python 数据类型,请自行实践。

⛳️ XML 格式文件

XML 也是一种常用的带格式的标记语言,其可用于文件形式共享和处理数据,其最大的亮点时以人类可读和机器可读的格式对文档内容进行标记。例如下述标记班级学员的 XML 文件。

<class>
    <student>
        <name>橡皮擦</name>
        <age>18</age>
    </student>
    <student>
        <name>小樱</name>
        <age>18</age>
    </student>
    <student>
        <name>魔法少女</name>
        <age>18</age>
    </student>
</class>

接下来依次说明一下各个单词的含义,其中每个单词都叫做一个节点,具体内容如下所示。

  • 根节点class 节点,任何 XML 文档有且仅有一个根节点;
  • 子节点:除了根节点以外的其它节点,都是子节点;
  • 标签:带尖括号的叫做标签,例如 <name>

书写 XML 文档的各个元素,要注意缩进,这里与 Python 缩进一致,都是采用 4 个空格(1 次 Tab 按键),每个节点(也可称作元素)可以添加属性,例如在上述 XML 文件中,增加如下内容。

<class>
    <student cardno="a001">
        <name>橡皮擦</name>
        <age>18</age>
    </student>
    <student cardno="a002">
        <name>小樱</name>
        <age>18</age>
    </student>
    <student cardno="a004">
        <name>魔法少女</name>
        <age>18</age>
    </student>
</class>

XML 文档中的文字,叫做文本。截至到这里,希望大家可以掌握一个 XML 文档包含三个重要部分,分别是元素,属性,文本。

可以使用本篇博客最开始的文本文件读写,对 XML 文件进行读写操作,也可以使用专用库进行操作。

Python 内置了 xml 模块操作 XML 文件,这里不在展开说明,如有必要,可以重点学习两部分知识点,罗列如下。

  • SAX:XML 简单处理 API,其主要用于读取和解析 XML 文件,并且 SAX 是只读的;
  • DOM:文档对象模型,它可以将整个 XML 文件读入到内存并以分层的形式存储 XML 文档的所有特征,而且可以修改 XML 文件,所以实战中一般会搭配 SAX 进行使用。

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 749 篇原创博客

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。