gpt4 book ai didi

python - 为什么 sys.getdefaultencoding() 与 sys.stdout.encoding 不同?这如何破坏 Unicode 字符串?

转载 作者:太空狗 更新时间:2023-10-29 21:03:37 27 4
gpt4 key购买 nike

我花了几个愤怒的时间寻找 Unicode 字符串的问题,这些字符串被分解为 Python (2.7) 对我隐藏的东西,但我仍然不明白。首先,我尝试在我的代码中始终使用 u".." 字符串,但这导致了臭名昭著的 UnicodeEncodeError。我尝试使用 .encode('utf8'),但这也无济于事。最后,事实证明我不应该使用任何一个,这一切都会自动解决。然而,我(在这里我需要感谢一位帮助过我的 friend )在用头撞墙时确实注意到了一些奇怪的事情。 sys.getdefaultencoding() 返回 ascii,而 sys.stdout.encoding 返回 UTF-8。 1. 在下面的代码中工作正常,无需对 sys 进行任何修改,并且 2. 引发 UnicodeEncodeError。如果我使用 reload(sys).setdefaultencoding("utf8") 更改默认系统编码,则 2. 工作正常。我的问题是为什么这两个编码变量首先不同,我如何设法在这段简单的代码中使用错误的编码?请不要将我发送到 Unicode HOWTO ,我已经在关于 UnicodeEncodeError 的几十个问题中明显地读到了这一点。

#  -*- coding: utf-8 -*-
import sys


class Token:
def __init__(self, string, final=False):
self.value = string
self.final = final

def __str__(self):
return self.value

def __repr__(self):
return self.value

print(sys.getdefaultencoding())
print(sys.stdout.encoding)

# 1.
myString = "I need 20 000€."
tok = Token(myString)
print(tok)

reload(sys).setdefaultencoding("utf8")

# 2.
myString = u"I need 20 000€."
tok = Token(myString)
print(tok)

最佳答案

My question is why the two encoding variables are different in the first place

它们有不同的用途。

sys.stdout.encoding 应该是您的终端用来解释文本的编码,否则您可能会在输出中得到 mojibake。在一个环境下可能是 utf-8,在另一个环境下可能是 cp437,等等。

sys.getdefaultencoding() 在 Python 2 上用于隐式转换(当编码未明确设置时),即 Python 2 可能将 ascii-only 字节串和 Unicode 字符串混合在一起,例如,xml.etree.ElementTree 将 ascii 范围内的文本存储为字节串或 json.dumps() returns an ascii-only bytestring instead of Unicode in Python 2 — 可能是由于性能 — 字节在表示 ascii 字符方面比 Unicode 便宜。 Python 3 中禁止隐式转换。

sys.getdefaultencoding() 在 Python 2 中的所有系统上始终是 'ascii' 除非您覆盖它,否则您不应该这样做,否则它可能会隐藏错误和您的数据由于对数据使用可能错误的编码的隐式转换,可能很容易损坏。

顺便说一句,还有另一种常见的编码 sys.getfilesystemencoding() 可能与两者不同。 sys.getfilesystemencoding() 应该是用于对操作系统数据(文件名、命令行参数、环境变量)进行编码的编码。

使用# -*- coding: utf-8 -*- 声明的源代码编码可能与所有已经提到的编码不同。

当然,如果你从文件、网络读取数据;它可能使用与上述不同的字符编码,例如,如果在记事本中创建的文件使用 Windows ANSI 编码(例如 cp1252)保存,则在另一个系统上,所有标准编码都可能与它不同。

重点是:由于与 Python 无关的原因,可能存在多种 编码,为了避免麻烦,请使用 Unicode 表示文本:尽快转换编码文本在输入上转换为 Unicode,并在输出时尽可能晚地将其编码为字节(可能使用不同的编码)——这就是所谓的 Unicode sandwich 的概念.

how do I manage to use the wrong encoding in this simple piece of code?

  1. 您的第一个代码示例不正确。您在 Python 2 的字节字符串中使用了您不应该做的非 ascii 文字字符。仅对二进制数据使用 bytestrings 的文字(或必要时所谓的 native 字符串)。如果您在任何不使用 utf-8 兼容编码的环境(例如 Windows 控制台)中使用 Python 2 运行它,该代码可能会产生诸如 I need 20 000Γé¼. 之类的 mojibake

  2. 假设 reload(sys) 不是其中的一部分,第二个代码示例就可以了。如果您不想在所有字符串文字前加上 u'' 前缀;你可以使用 from __future__ import unicode_literals

您的实际问题是 UnicodeEncodeError 错误,reload(sys) 不是正确的解决方案!
正确的解决办法是configure your locale properly on POSIX (LANG, LC_CTYPE)set PYTHONIOENCODING envvar if the output is redirected to a pipe/file or install win-unicode-console to print Unicode to Windows console .

关于python - 为什么 sys.getdefaultencoding() 与 sys.stdout.encoding 不同?这如何破坏 Unicode 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15530635/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com