这里的问题是.write
文件对象的方法天真地试图将unicode
你传递给字节字符串的 unicode 字符串(如果你在 Python 2.x 中,这将是类型)转换为字节字符串(如果你在 Python 2.x,这将是str
使用 ASCII 编解码器的类型),但是您传递的 unicode 字符串不能使用 ASCII 表示,因为它具有不属于 ASCII 字符集的(日语)字符。
您需要使用.encode
unicode 字符串的方法将其转换为代表该字符串的一系列字节,然后才能保存它。这基本上就是str
Python 2.x 中的类型所代表的 - 只是一系列字节,而不是您可能期望的一系列字符。但是,Python 很容易让您产生其他想法,因为当您print
使用 type 变量时str
,Python 会使用系统默认的 unicode 编码将其显示为终端中的一系列字符。
您应该在此处使用什么编码来对字符串进行编码取决于您的用例。UTF-8 是最常见的,您可能只是想使用它,但如果您想确保您正在写入的文件将在同一系统的文本编辑器中正确显示,即使您在设备上运行它一个不太常见的系统编码,如 UTF-16,您可能希望使用系统的默认编码(如果系统具有无法对您的字符串进行编码的默认编码,这当然会失败)。
换句话说,您几乎肯定想做以下事情之一:
一种)
f.write(textwrap.dedent(the_string).encode('utf-8'))
b)
import sys
f.write(textwrap.dedent(the_string).encode(sys.getdefaultencoding()))
如果你认为这是一个相当烦人且复杂的负载,让你的头脑开始执行将一些非 ASCII 文本写入文件的相当基本的任务,那么 - 我同意你的看法!当我开始使用 Python(这是我的第一门编程语言)时,我在理解 unicode、字符串编码以及与之相关的 Python 类型和方法方面遇到了很多困难。然而,复杂性并不是 Python 的错——这取决于计算机对文本进行编码的方式,尤其是文本有多种编码这一事实。不同系列的字节可以表示同一系列的字符,取决于正在使用的编码。这使得 Python 不可能只对你隐瞒字符串编码的具体细节,并且像我一样“自动做一些明智的事情”,作为一个菜鸟,天真地希望并期待它会。
如果您要编写大量代码,涉及从 Web 获取和使用可能包含非 ASCII 字符的文本数据,我建议您彻底阅读该主题并深入了解它,两者都来自一般和特定于 Python 的观点。