Weibw's World Weibw's World
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Weibw

一个没有梦想的咸鱼
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《Flask》

  • 《Python Cookbook》第三版

    • 第一章:数据结构与算法

    • 第二章:字符串和文本

    • 第三章:数字日期和时间

    • 第四章:迭代器与生成器

    • 第五章:文件与IO

      • 读写文本数据
        • 问题
        • 解决方案
        • 讨论
      • 打印输出至文件中
      • 使用其他分隔符或行终止符打印
      • 读写字节数据
      • 文件不存在才能写入
      • 字符串的IO操作
      • 读写压缩文件
      • 固定大小记录的文件迭代
      • 读取二进制数据到可变缓冲区中
      • 内存映射的二进制文件
      • 文件路径名的操作
      • 测试文件是否存在
      • 获取文件夹中的文件列表
      • 忽略文件名编码
      • 打印不合法的文件名
      • 增加或改变已打开文件的编码
      • 将字节写入文本文件
      • 将文件描述符包装成文件对象
      • 创建临时文件和文件夹
      • 与串行端口的数据通信
      • 序列化Python对象
    • 第六章:数据编码和处理

    • 第七章:函数

    • 第八章:类与对象

    • 第九章:元编程

    • 第十章:模块与包

    • 第十一章:网络与Web编程

    • 第十二章:并发编程

    • 第十三章:脚本编程与系统管理

    • 第十四章:测试、调试和异常

    • 第十五章:C语言扩展

  • Python基础

  • Python
  • 《Python Cookbook》第三版
  • 第五章:文件与IO
weibw
2022-01-07

读写文本数据

# 问题

你需要读写各种不同编码的文本数据,比如ASCII,UTF-8或UTF-16编码等。

# 解决方案

使用带有 rt 模式的 open() 函数读取文本文件。如下所示:

# Read the entire file as a single string
with open('somefile.txt', 'rt') as f:
    data = f.read()

# Iterate over the lines of the file
with open('somefile.txt', 'rt') as f:
    for line in f:
        # process line
        ...
1
2
3
4
5
6
7
8
9

类似的,为了写入一个文本文件,使用带有 wt 模式的 open() 函数, 如果之前文件内容存在则清除并覆盖掉。如下所示:

# Write chunks of text data
with open('somefile.txt', 'wt') as f:
    f.write(text1)
    f.write(text2)
    ...

# Redirected print statement
with open('somefile.txt', 'wt') as f:
    print(line1, file=f)
    print(line2, file=f)
    ...
1
2
3
4
5
6
7
8
9
10
11

如果是在已存在文件中添加内容,使用模式为 at 的 open() 函数。

文件的读写操作默认使用系统编码,可以通过调用 sys.getdefaultencoding() 来得到。 在大多数机器上面都是utf-8编码。如果你已经知道你要读写的文本是其他编码方式, 那么可以通过传递一个可选的 encoding 参数给open()函数。如下所示:

with open('somefile.txt', 'rt', encoding='latin-1') as f:
    ...
1
2

Python支持非常多的文本编码。几个常见的编码是ascii, latin-1, utf-8和utf-16。 在web应用程序中通常都使用的是UTF-8。 ascii对应从U+0000到U+007F范围内的7位字符。 latin-1是字节0-255到U+0000至U+00FF范围内Unicode字符的直接映射。 当读取一个未知编码的文本时使用latin-1编码永远不会产生解码错误。 使用latin-1编码读取一个文件的时候也许不能产生完全正确的文本解码数据, 但是它也能从中提取出足够多的有用数据。同时,如果你之后将数据回写回去,原先的数据还是会保留的。

# 讨论

读写文本文件一般来讲是比较简单的。但是也几点是需要注意的。 首先,在例子程序中的with语句给被使用到的文件创建了一个上下文环境, 但 with 控制块结束时,文件会自动关闭。你也可以不使用 with 语句,但是这时候你就必须记得手动关闭文件:

f = open('somefile.txt', 'rt')
data = f.read()
f.close()
1
2
3

另外一个问题是关于换行符的识别问题,在Unix和Windows中是不一样的(分别是 \n 和 \r\n )。 默认情况下,Python会以统一模式处理换行符。 这种模式下,在读取文本的时候,Python可以识别所有的普通换行符并将其转换为单个 \n 字符。 类似的,在输出时会将换行符 \n 转换为系统默认的换行符。 如果你不希望这种默认的处理方式,可以给 open() 函数传入参数 newline='' ,就像下面这样:

# Read with disabled newline translation
with open('somefile.txt', 'rt', newline='') as f:
    ...
1
2
3

为了说明两者之间的差异,下面我在Unix机器上面读取一个Windows上面的文本文件,里面的内容是 hello world!\r\n :

>>> # Newline translation enabled (the default)
>>> f = open('hello.txt', 'rt')
>>> f.read()
'hello world!\n'

>>> # Newline translation disabled
>>> g = open('hello.txt', 'rt', newline='')
>>> g.read()
'hello world!\r\n'
>>>
1
2
3
4
5
6
7
8
9
10

最后一个问题就是文本文件中可能出现的编码错误。 但你读取或者写入一个文本文件时,你可能会遇到一个编码或者解码错误。比如:

>>> f = open('sample.txt', 'rt', encoding='ascii')
>>> f.read()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python3.3/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
12: ordinal not in range(128)
>>>
1
2
3
4
5
6
7
8
9

如果出现这个错误,通常表示你读取文本时指定的编码不正确。 你最好仔细阅读说明并确认你的文件编码是正确的(比如使用UTF-8而不是Latin-1编码或其他)。 如果编码错误还是存在的话,你可以给 open() 函数传递一个可选的 errors 参数来处理这些错误。 下面是一些处理常见错误的方法:

>>> # Replace bad chars with Unicode U+fffd replacement char
>>> f = open('sample.txt', 'rt', encoding='ascii', errors='replace')
>>> f.read()
'Spicy Jalape?o!'
>>> # Ignore bad chars entirely
>>> g = open('sample.txt', 'rt', encoding='ascii', errors='ignore')
>>> g.read()
'Spicy Jalapeo!'
>>>
1
2
3
4
5
6
7
8
9

如果你经常使用 errors 参数来处理编码错误,可能会让你的生活变得很糟糕。 对于文本处理的首要原则是确保你总是使用的是正确编码。当模棱两可的时候,就使用默认的设置(通常都是UTF-8)。

编辑 (opens new window)
上次更新: 2023/10/13, 17:39:25
迭代器代替while无限循环
打印输出至文件中

← 迭代器代替while无限循环 打印输出至文件中→

最近更新
01
牛客网非技术快速入门SQL练习题
03-08
02
其他日常SQL题
03-07
03
用户与权限管理
03-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 | Weibw | 辽ICP备18015889号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式