UnicodeEncodeError:“charmap”编解码器不能将-字符映射编码为<未定义>

UnicodeEncodeError:“charmap”编解码器不能将-字符映射编码为<未定义>,打印函数

我正在编写Python(Python3.3)程序,使用POST方法将一些数据发送到网页。在调试过程中,我主要是获取页面结果并将其显示在屏幕上。print()功能。

代码如下:

conn.request("POST", resource, params, headers)response = conn.getresponse()print(response.status, response.reason)data = response.read()
print(data.decode('utf-8'));

这个HTTPResponse .read()方法返回bytes元素编码页面(这是一个格式良好的UTF-8文档),直到我停止对Windows使用空闲GUI,转而使用Windows控制台为止,这似乎还不错。返回的页面有一个U+2014字符(em-破折号),打印函数在WindowsGUI中翻译得很好(我猜代码页1252),但在Windows控制台(代码页850)中没有。鉴于strict默认行为我得到以下错误:

UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>

我可以用这个非常难看的代码来修复它:

print(data.decode('utf-8').encode('cp850','replace').decode('cp850'))

现在,它将冒犯性字符“-”替换为?..不是理想的情况(连字符应该是一个更好的替代),但足够好我的目的。

有几件事我不喜欢从我的解决方案。

  1. 在所有这些解码、编码和解码中,代码都是丑陋的。
  2. 它解决了这个案子的问题。如果我使用其他编码(拉丁文-1,cp 437,回cp 1252等)将程序移植到系统它应该识别目标编码。但事实并非如此。(例如,当再次使用空闲的GUI时,Emdash s也会丢失,这在以前没有发生过)
  3. 如果埃达什能翻译成连字符而不是审讯声,那就更好了。

问题不在于Emdash(我可以想出解决这个问题的几种方法),但我需要编写健壮的代码。我给页面提供了数据库中的数据,这些数据可以返回。我可以预见到许多其他相互矛盾的情况:“U+00c1”(在我的数据库中是可能的)可以转换为CP-850(DOS/Windows控制台编码,用于西欧语言),但不能转换为CP-437(美国英语的编码,这在许多Windows分期付款中都是默认的)。

因此,问题是:

是否有更好的解决方案使我的代码与输出接口编码无关?


慕哥9229398
浏览 1428回答 3
3回答

互换的青春

基于DirkSt cker的回答,这里为Python 3的打印函数提供了一个简洁的包装函数。用它就像你会用印刷品一样。作为额外的奖励,与其他答案相比,这不会将文本打印为字节数组(‘b“content”’),而是作为普通字符串(‘content’)打印,因为最后一个解码步骤。def&nbsp;uprint(*objects,&nbsp;sep='&nbsp;',&nbsp;end='\n',&nbsp;file=sys.stdout): &nbsp;&nbsp;&nbsp;&nbsp;enc&nbsp;=&nbsp;file.encoding&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;enc&nbsp;==&nbsp;'UTF-8': &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(*objects,&nbsp;sep=sep,&nbsp;end=end,&nbsp;file=file) &nbsp;&nbsp;&nbsp;&nbsp;else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;=&nbsp;lambda&nbsp;obj:&nbsp;str(obj).encode(enc,&nbsp;errors='backslashreplace').decode(enc) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(*map(f,&nbsp;objects),&nbsp;sep=sep,&nbsp;end=end,&nbsp;file=file)uprint('foo')uprint(u'Antonín&nbsp;Dvořák')uprint('foo',&nbsp;'bar',&nbsp;u'Antonín&nbsp;Dvořák')

素胚勾勒不出你

为了调试目的,可以使用print(repr(data)).若要显示文本,请始终打印Unicode。不要硬编码环境中的字符编码,例如cp850在你的剧本里。要解码http响应,请参见用Python获取HTTP响应的字符集/编码的好方法.要将Unicode打印到Windows控制台,您可以使用win-unicode-console包装.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python