用Python读写文件(指南)
[TOC]
使用Python最常见的任务之一是读取和写入文件。无论是写入简单的文本文件,读取复杂的服务器日志,甚至是分析原始字节数据,所有这些情况都需要读取或写入文件。
在本教程中,您将学习:
什么组成了一个文件,为什么它在python中很重要
用Python读写文件的基础知识
读写文件的一些基本场景
本教程主要针对初学者到中级的 Pythonistas,但这里有一些提示,更高级的程序员可能也会从中受益。
什么是文件?
在讨论如何使用Python中的文件之前,了解文件的具体内容以及现代操作系统如何处理它们是很重要的。
从本质上讲,文件是用于存储数据的连续字节集。这些数据以特定格式组织,可以是任何像文本文件一样简单的数据,也可以像程序可执行文件一样复杂。最后,这些字节文件被翻译成二进制文件1,0以便计算机更容易处理。
大多数现代文件系统上的文件由三个主要部分组成:
标题(Header):有关文件内容的元数据(文件名,大小,类型等)
数据(Data):由创建者或编辑者编写的文件内容
文件结束符(EOF):表示文件结尾的特殊字符
FileFormat.02335d06829d.png
数据表示的内容取决于所使用的格式规范,通常由扩展名表示。例如,具有.gif扩展名的文件最可能符合GIF规范。有数百个(甚至上千个)文件扩展名。对于本教程,您将只处理.txt或.csv文件扩展名。
文件路径
在操作系统上访问文件时,需要文件路径。文件路径是表示文件位置的字符串。它分为三个主要部分:
文件夹路径:文件系统上的文件夹位置,后续文件夹由正斜杠/(Unix)或反斜杠\(Windows)分隔
文件名:文件的实际名称
扩展名:文件路径的末尾(句号(.)后的内容),用于表示文件类型
这是一个简单的例子。假设您有一个位于文件结构中的文件,如下所示:
/
│
├── path/
| │
│ ├── to/
│ │ └── cats.gif
│ │
│ └── dog_breeds.txt
|
└── animals.csv
假设您要访问cats.gif文件,并且您当前的位置位于文件夹path中。要访问该文件,您需要浏览该path文件夹,然后查看to文件夹,最后到达cats.gif文件。文件夹路径是path/to/。文件名是cats。文件扩展名是.gif。所以完整的道路是path/to/cats.gif。
现在假设您当前的位置或当前工作目录(cwd)位于我们的示例文件夹结构的to文件夹中。可以通过文件名和扩展名cats.gif简单地引用文件,而不用引用完整路径path/to/cats.gif。
/
│
├── path/
| │
| ├── to/ ← 你的当前工作目录 (cwd)在这儿
| │ └── cats.gif ← 访问这个文件
| │
| └── dog_breeds.txt
|
└── animals.csv
但如果要访问dog_breeds.txt呢?如果不使用完整路径,您将如何访问?您可以使用特殊字符double-dot(..)来移动到上一个目录。这意味着../dog_breeds.txt会从文件夹to引用到dog_breeds.txt:
/
│
├── path/ ← 引用该父目录
| │
| ├── to/ ← 当前工作目录 (cwd)
| │ └── cats.gif
| │
| └── dog_breeds.txt ← 访问该文件
|
└── animals.csv
double-dot(..)可以链接在一起以遍历当前目录上的多个目录。例如,要从to文件夹访问animals.csv,您将使用../../animals.csv。
Line Endings
处理文件数据时经常遇到的一个问题是新行或行结尾的表示。行结尾起源于莫尔斯电码时代,那时一个特定的符号被用来传达传输的结束或一条线的末端。
后来,国际标准化组织(ISO)和美国标准协会(ASA)对电传打字机进行了标准化。ASA标准规定行尾应使用回车(序列CR或\r)和换行(LF或\n)字符(CR+LF或\r\n)。然而,ISO标准允许CR+LF字符或仅LF字符.
Windows使用CR+LF字符表示新行,而Unix和较新的Mac版本仅使用LF字符。当您在不同于文件源的操作系统上处理文件时,这可能会导致一些复杂情况。以下是一个简单的例子。假设我们检查在Windows系统上创建的文件dog_breeds.txt:
哈巴狗\r\n
杰克罗素梗犬\r\n
英国史宾格犬\r\n
德国牧羊犬\r\n
斯塔福郡斗牛梗\r\n
骑士国王查尔斯猎犬\r\n
金毛猎犬\r\n
西部高地白梗\r\n
拳击手\r\n
边境猎犬\r\n
同样的输出将在Unix设备上以不同方式解释:
哈巴狗\r
\n
杰克罗素梗犬\r
\n
英国史宾格犬\r
\n
德国牧羊犬\r
\n
斯塔福郡斗牛梗\r
\n
骑士国王查尔斯猎犬\r
\n
金毛猎犬\r
\n
西部高地白梗\r
\n
拳击手\r
\n
边境猎犬\r
\n
这会使每一行的迭代都有问题,您可能需要考虑这样的情况。
字符编码
您可能面临的另一个常见问题是字节数据的编码。编码是从字节数据到人类可读字符的转换。这通常通过指定表示字符的数值来完成。两种最常见的编码是ASCII和UNICODE格式。ASCII只能存储128个字符,而Unicode最多可包含1,114,112个字符。
ASCII实际上是Unicode(UTF-8)的子集,这意味着ASCII和Unicode共享相同的数字到字符值。重要是要注意,使用不正确的字符编码解析文件可能会导致字符失败或误传。例如,如果文件是使用UTF-8编码创建的,并且您尝试使用ASCII编码对其进行解析,则如果存在超出128个值的字符,则会引发错误。
在Python中打开和关闭文件
当您想使用文件时,首先要做的就是打开它。这是通过调用open()内置函数完成的。open()有一个必需的参数,就是文件的路径。open()有一个返回,就是文件对象:
file = open('dog_breeds.txt')
打开文件后,接下来要学习的是如何关闭它。
:exclamation: 警告:
您应始终确保正确关闭打开的文件。
重要的是要记住,关闭文件是您的责任。在大多数情况下,在应用程序或脚本终止时,文件最终将被关闭。然而,并不能保证任何时候都会发生这种情况。这可能导致不必要的行为,包括资源泄漏。确保您的代码以明确定义的方式运行并减少任何不需要的行为, 这也是Python(Pythonic)中的最佳实践。
当您操作文件时,有两种方法可以确保文件正确关闭,即使遇到错误也是如此。关闭文件的第一种方法是使用try-finally块:
reader = open('dog_breeds.txt')
try:
# 在这儿做进一步的文件处理
finally:
reader.close()
关闭文件的第二种方法是使用如下的with语句:
with open('dog_breeds.txt') as