问题。
我使用的是基于 Sublime Text 3 构建的 Python 2.7,打印时遇到问题。
在某些情况下,对于 '\uFFFD'
- 'REPLACEMENT CHARACTER'
,我会得到一个非常困惑的输出。
例如:
print u'\ufffd' # should be '�' - the 'REPLACEMENT CHARACTER'
print u'\u0061' # should be 'a'
-----------------------------------------------------
[Finished in 0.1s]
顺序反转后:
print u'\u0061'
print u'\ufffd'
-----------------------------------------------------
a
�
[Finished in 0.1s]
因此,Sublime 可以打印出 '�' 字符,但由于某些原因在第一种情况下不这样做。
而且输出对语句顺序的依赖似乎很奇怪。
替换字符的问题通常会导致非常不可预测的打印输出行为。
例如,我想打印出带有错误替换的解码字节:
cp1251_bytes = '\xe4\xe0' # 'да' in cp1251
print cp1251_bytes.decode('utf-8', errors='replace')
-----------------------------------------------------
��
[Finished in 0.1s]
让我们替换字节:
cp1251_bytes = '\xed\xe5\xf2' # 'нет' in cp1251
print cp1251_bytes.decode('utf-8', errors='replace')
-----------------------------------------------------
[Finished in 0.1s]
再添加一条打印语句:
cp1251_bytes = '\xed\xe5\xf2' # 'нет' in cp1251
print cp1251_bytes.decode('cp1251')
print cp1251_bytes.decode('utf-8', errors='replace')
-----------------------------------------------------
нет
���
[Finished in 0.1s]
下面是一些其他测试用例的实现说明:
总结,在描述的打印输出行为中有以下模式:
'\ufffd'
字符的偶数/奇数
我的问题:
我的 Python 2.7 sublime-build 文件:
{
"cmd": ["C:\\_Anaconda3\\envs\\python27\\python", "-u", "$file"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"env": {"PYTHONIOENCODING": "utf-8"}
}
对于与 Anaconda 分开安装的 Python 2.7,行为完全相同。
最佳答案
我已经重现了您的问题,并且找到了一个无论如何都能在我的平台上运行的解决方案:删除 -u
来自你的旗帜 cmd
构建配置选项。
我不是 100% 确定为什么会这样,但这似乎是控制台解释包含多字节字符的无缓冲数据流导致的交互不良。这是我发现的:
-
-u
option将 Python 的输出切换为无缓冲 - 这个问题根本不是替换字符所特有的。我对其他字符(如“あ”(U+3042))也有类似的行为。
- 其他编码也会出现类似的不良结果。设置
"env": {"PYTHONIOENCODING": "utf-16be"}
结果print u'\u3042'
输出0B
.
最后一个编码设置为 UTF-16BE 的示例说明了我的想法。控制台一次接收一个字节,因为输出是无缓冲的。所以它收到 0x30
字节优先。然后控制台确定这不是有效的 UTF-16BE 并决定回退到 ASCII,因此输出 0
.它当然会在之后立即接收下一个字节并遵循相同的逻辑输出 B
.
使用 UTF-8 编码,控制台接收到不可能被解释为 ASCII 的字节,所以我相信控制台在正确解释无缓冲流方面做得稍微好一些,但它仍然遇到困难你的问题指出了这一点。
关于基于 Sublime Text 3 的 Python 2.7 不打印 '\uFFFD' 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46856584/