【问题标题】:When writing files, will the encoding used by open ever depend on the string you are writing?写入文件时,open 使用的编码是否会依赖于您正在写入的字符串?
【发布时间】:2021-07-30 18:28:22
【问题描述】:

每天fetch_poem() 检索一首诗。每周一,诗歌会在周二以英文回归;丹麦语,周三;挪威语……等等。

我每天将这些诗写到位于path 的文件中:

my_poem = fetch_poem()
with open(path, "w") as f:  # 
    f.write(my_poem)

我的问题是,编码可以取决于字符串中的字母/字符/语言吗?我从来没有明确地将编码传递给open()

Documentation 说:

encoding 是用于对文件进行解码或编码的编码名称。这应该只在文本模式下使用。默认编码取决于平台(无论 locale.getpreferredencoding() 返回什么),但可以使用 Python 支持的任何文本编码。

我的locale.getpreferredencoding

我使用的是丹麦语区域设置的 Windows 服务器。运行 getpreferredencoding() 会得到 cp1252

$ python -c "import locale; print(locale.getpreferredencoding(do_setlocale=True))"
cp1252

这是否意味着 cp1252 用于对我的所有文件进行编码?

【问题讨论】:

  • 可能,并且仅在 Windows 中(以及某些 Windows 版本和某些位置),以及 Python 的实际版本。所以:在open 上明确编码:减少意外,它也可以作为文档。 [顺便说一句:更喜欢 UTF-8]
  • 一首非 UTF-8 字符的诗歌被提取的那一天,程序将出错。我可以将文件写入包装在 try-except UnicodeDecodeError 中并尝试 fetch_poem() 直到获取符合 UTF-8 的文件。这不是一个非常优雅的解决方案。一般来说,我同意,所有情况下“只使用 X”的解决方案都是黄金。
  • UTF-8 编码 Unicode,因此它应该包含所有字符。 Windows 不支持 Unicode 以外的字符,Python 字符串应该已经是 unicode。 [注意 ASCII 和 Latin1 以及所有 Windows 代码页都是 Unicode 的子集)——否则您将写入二进制文件(带有b 标志)
  • 这取决于你以后想对这些诗做什么。如果您使用需要特定编码的应用程序处理它们,请使用该编码。顺便提一句。对于您的问题,是的,在您的系统上,cp1252 将用于所有文件。

标签: python encoding


【解决方案1】:

是的,open() 将使用您所在地区的首选编码,如果您不拼写编码。

支持任意语言的正确解决方法是使用 Unicode 编码并显式传递它。

with open(path, 'w', encoding='utf-8') as f:
    f.write(my_poem)

我建议使用 UTF-8,但如果您是 Windows 受害者,也许 UTF-16le 在某种意义上也可以,嗯,是有道理的。它还取决于将要使用此文件的内容。在 Windows 上,可能使用 utf-8-sig 而不是 utf-8,即使在 UTF-8 中使用 BOM 由于其他原因存在问题。

您在问题下方的一个 cmets 暴露了对它的工作原理的误解。如果fetch_poem() 返回文本,那只是Unicode,而不是任何特定的编码。 Python 3 完全为您屏蔽了内存中字符串的这些细节;当您需要将它们与外界通信(写入文件,通过网络发送等)时,您需要对它们进行编码。不妨查看 Ned Batchelder 的 Pragmatic Unicode 以获得很好的介绍。

不管怎样,代码页 1252 支持 most大多数 文化占主导地位的西欧语言(包括丹麦语和挪威语,但不包括例如萨米语和世界语)中的字符串,但如果您需要不寻常的变音符号,或者当然是非拉丁语言,它就会崩溃。 Unicode 优雅地解决了所有这些问题,并且 Unicode 序列化格式应该是您对任何文本文件的首选编码。

【讨论】:

  • Python 3 并不能保护您免受 Unicode 的怪癖,例如不同的组合形式。此外,说 Unicode 是文本文件的一种格式并不完全正确—— Unicode 本身只是标准映射; UTF-8(以及其他,包括 cp1252)是文本编码。
  • @AKX 尚不清楚这些 cmets 如何与此答案相关。我没有找到我声称 Unicode 是文本文件格式的地方,尽管我稍微调整了最后一句话。我并没有声称 Python 可以保护您免受 Unicode 的怪癖影响。我是说 Python 在您处理字符串时可以保护您免受编码问题的影响。
  • 是的,最后一句话(合并格式和编码)是我的问题。现在好多了 :) 关于 Unicode 怪癖,只是想把它放在那里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多