写入文件时,open 使用的编码是否会依赖于您正在写入的字符串?

When writing files, will the encoding used by open ever depend on the string you are writing?

每天fetch_poem()检索一首诗。星期一,诗歌以英语返回,星期二;丹麦语,每周三;挪威语...等等。

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

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

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

Documentation 说:

encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever locale.getpreferredencoding() returns), but any text encoding supported by Python can be used.

我的locale.getpreferredencoding

我在丹麦语言环境的 Windows 服务器上。 运行 getpreferredencoding() 给出 cp1252:

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

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

是的,如果您不拼写编码,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 出于其他原因是有问题的。

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

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