Python 3.2 UnicodeEncodeError: 'charmap' codec can't encode character '\u2013' in position 9629: character maps to 问题的出现的原因是Python 3中使用了Unicode,但是Windows控制台或POSIX tty不支持Unicode。所以当你使用print或者将Unicode字符串发送到stdout时,Python需要对其进行编码。错误信息间接地告诉你Python尝试使用的字符集是cp850。你可以通过'\u2013'.encode('cp850')来测试这个字符集是否包含适当的字符,或者在网上查找cp850的相关信息。
可能是Python猜测错误,你的控制台实际上是设置为UTF-8。在这种情况下,只需手动设置sys.stdout.encoding='utf-8'。也有可能是你本意是将控制台设置为UTF-8但是做错了操作。在这种情况下,你可能需要在superuser.com上寻求帮助。
但是,如果没有问题,你将无法打印该字符。你需要使用非严格的错误处理程序手动对其进行编码。例如:
>>> '\u2013'.encode('cp850')
UnicodeEncodeError: 'charmap' codec can't encode character '\u2013' in position 0: character maps to
>>> '\u2013'.encode('cp850', errors='replace')
b'?'
那么,如何打印无法在控制台上打印的字符串呢?
你可以将每个print函数替换为以下代码:
>>print(r['body'].encode('cp850', errors='replace').decode('cp850'))
?
...但是这样做会变得非常乏味。
简单的方法就是设置sys.stdout上的错误处理程序:
>>sys.stdout.errors = 'replace'
>>print(r['body'])
?
对于打印到文件,情况基本相同,只是你不必在事后设置f.errors,你可以在构造时设置它。不是这样:
with open('path', 'w', encoding='cp850') as f:
这样做:
with open('path', 'w', encoding='cp850', errors='replace') as f:
或者,如果你可以使用UTF-8文件,就像Mark Ransom的答案所示,只需这样做:
with open('path', 'w', encoding='utf-8') as f:
我尝试了你的建议,错误消失了,但文件中的文本每行打印一个字符,这导致浏览器无法正确解析文件。有什么解决方法或原因吗?我在错误中说cp1252.py文件被使用,所以我将编码从cp850更改为cp1252,但原则应该是相同的对吗?
是的,对于任何没有完全覆盖Unicode的编解码器(基本上是除了utf-8和utf-7之外的所有编解码器),原则都是相同的。我很好奇你是如何在这里粘贴错误时得到cp850的,如果你真正使用的是cp1252。你从哪里复制和粘贴这个错误消息的?
同时...每行只有一个字符的最常见原因是将字符串视为代码中的字符串序列。 (字符串是一个由1个字符字符串组成的序列,所以它是有效的,但不是你希望的方式。)但是我们必须看到相关的代码才能帮助你调试。而且这几乎肯定是一个完全独立的问题,所以你可能应该创建一个新问题。
举个例子,你可能会遇到这个每行一个字符的问题...如果你做的是bodies = [row['body'] for row in c.fetchall()]然后是for body in bodies: print(body),这是正确的。但是如果你做的是bodies = c.fetchone()['body']然后是for body in bodies: print(body),它会逐个字符地给你输出。
我从我在控制台中重新创建的较小的示例代码中获得了错误消息。
谢谢,那我想问题出在哪里。我有一个接受文件和要打印的内容的print函数,它假设它是一个元组。for循环将变成你示例中的最后一个for循环。
谢谢,问题解决了,通过将['body']转换为元组,解决了每行一个字符的问题。
这听起来正确。你的代码假设一个字符串元组,但只得到一个字符串,所以它会将字符串视为一个字符的元组。很高兴你解决了这个问题。