提问人:Watchduck 提问时间:9/19/2023 最后编辑:Watchduck 更新时间:9/19/2023 访问量:101
Python 在读取或写入文件时是否始终使用 UTF-8?(仅使用文件和模式参数打开函数。
Does Python always use UTF-8 when reading from or writing to a file? (Open function with only file and mode args.)
问:
我的印象是,读取和写入文件总是使用 UTF-8。
我试图通过对脚本使用不同的编码来找到一个反例,但没有找到。
我的示例使用 Yen-Symbol,其 UTF-8 编码为 。C2 A5
'¥'.encode('utf-8') == b'\xc2\xa5'
假设文件yen.txt,其中包含两个字节。
在哪些情况下,以下代码可能会失败?C2 A5
with open('yen.txt', 'r') as f:
assert f.read() == '¥'
或者下面的代码可以生成一个不包含字节的文本文件吗?C2 A5
with open('yen.txt', 'w') as f:
f.write('¥')
我所说的“情况”是指脚本的编码或操作系统的某些设置。
假设脚本使用某种编码,允许 Yen-Symbol。
(否则,它相当于一个问号。
我尝试了 编写脚本,结果是一样的。
我想知道,文本文件是否可能只包含字节,
因为这是 CP 437 中日元符号的码位。# coding: cp437
9D
'¥'.encode('cp437') == b'\x9d'
顺便说一句,我在 GitHub 上上传了修改后的脚本,不知何故日元符号消失了。
有人知道为什么吗?
答:
-1赞
Watchduck
9/19/2023
#1
正如 Mark Tolonen 所指出的,编码实际上并没有默认值。
在函数的注释中,它声明如下:open
在文本模式下,如果未指定编码,则使用的编码为 platform dependent:被调用以获取 当前区域设置编码。
(对于读取和写入原始字节,请使用二进制 模式,并保留未指定编码。locale.getpreferredencoding(False)
在 Linux 和 Mac 上,首选编码可能是 ,在 Windows 上可能是 。'UTF-8'
'cp1252'
>>> import locale
>>> locale.getpreferredencoding(True)
'UTF-8'
评论
0赞
Joachim Sauer
9/19/2023
你确定最后一句话吗?平台默认编码是 UTF-8 几乎是所有现代类 unix 操作系统(包括 Linux、Mac OS X 和 Android),但在 Windows 中,它通常是不同的编码(具体不知道 Python,但 Java 面临同样的问题)。这个答案看起来像是“它在我的机器上工作”的经典案例。
0赞
Watchduck
9/19/2023
你是对的。在 Windows 上,它是 .Windows-1252 (所以我想在 Windows 上,如果没有指定编码,“¥”应该保存为 A5。'cp1252'
0赞
Joachim Sauer
9/19/2023
甚至这个答案也是不完整的。在 Windows 上,这取决于配置的区域设置。理智的做法是不要对该函数的返回值进行任何假设。如果需要 UTF-8,请指定它。如果需要平台默认编码,请显式获取该编码(或者不提供编码并默认使用它)。
评论
encoding
open()
open('yen.txt', 'rb')
open('yen.txt', 'r')
utf-8
locale.getencoding()
AttributeError: module 'locale' has no attribute 'getencoding'
locale.getpreferredencoding()