python 3.6.7 centos 7机器UnicodeEncodingError

python 3.6.7 UnicodeEncodingError in centos 7 machine

在进入问题之前,我想告知我看到了很多关于这个问题的 Whosebug 问题和 python 错误报告,但我无法找出问题的根源

我在 centos 机器上遇到 UnicodeEncodingError。 Python 不是内置在机器中,而是具有所需 python 版本 (3.6.7) 的虚拟环境是在其他地方构建并复制到这里的。所以在启动服务器的同时,我们激活虚拟环境,启动服务器。

在两种情况下观察到该问题

  1. 记录其中包含Unicode字符的输入请求参数
  2. 我们将打印语句通过管道传输到一个日志文件,我可以在尝试通过代码打印此 Unicode 字符串时看到错误

错误如下所示

print("\u6211\u7684\u7535\u8111\u603b\u662f\u51fa\u73b0Windows\u9700\u8981\u6fc0\u6d3b")
UnicodeEncodeError: 'ascii' codec can't encode characters in position 56-63: ordinal not in range(128)

我通过 python 终端验证了关注

我经历了一些要求修改 LC_ALL 或在环境变量中添加 PYTHONIOENCODING 的解决方案,但我不确定是否在不知道副作用的情况下修改它们,因为环境是生产环境。

编辑- 我试图通过打开 python 终端并毫无问题地打印它们来打印同一组字符,这些字符在上述尝试中破坏了代码。 试过这样打印

import sys
print("日本語")
sys.stdout.write("日本語\n")

但是通过代码,它引发了 UnicodeEncodingError

我想知道如何解决这个问题?

谢谢

大多数 ascii 终端无法呈现 unicode 字符(您可以尝试更改字体...也许这会起作用)...所以即使您通过了编码错误,您的 打印可能看起来像 �������Windows�������

如果你 运行 它处于空闲状态它会工作......

我会 强烈 推荐 print(repr(string_that_might_have_unicode)) 因为这将保证 ascii 可打印表示...没有什么比因为您试图打印而使您的应用程序崩溃更糟糕的了一些调试信息... (打印 repr 会更像 b"'\u6211\u7684\u7535\u8111\u603b\u662f\u51fa\u73b0Windows\u9700\u8981\u6fc0\ u6d3b'"

您也可以在打印前尝试encode手动

print(my_unicode_string.encode("utf8"))

可能工作...在某些终端...但实际上...只是打印 repr 除非你向用户展示它(但既然你谈论服务器我想这不是终端客户端应用程序,而是正在打印的调试信息(并重定向到日志文件?))

如果您真的需要将确切的 unicode 打印到终端而不是 repr,那么我认为您需要执行手动解码步骤以将 utf8 发送到实际的终端……但是始终打印要容易得多记录时的 repr(这有利于向您显示不可见和空白字符......但如果它是客户端应用程序的一部分则效果不佳)

终于解决了这个问题

我在两种不同的情况下观察到问题中提到的问题

第一种情况——在问题中发布了所有设置,所有与语言相关的编码都是 UTF-8,它在我们的产品服务器重新启动后没有任何变化就起作用了。仍然不知道是什么让它以前不能工作,重启机器后才能工作。

第二种情况 - 在我们的客户端环境中,所有 LC 变量都设置为 POSIX。我经历了许多建议将 LANG 或 LC_ALL 修改为 UTF-8 的解决方案。但是更改所有编码配置可能会导致诸如日期时间转换等问题……这些都是基于语言环境的。

Fix - only changed LC_CTYPE to UTF-8 in our case it is en_US.UTF-8

export LC_CTYPE="en_US.UTF-8"

它奏效了。