小能豆

Sublime Text 3 上的 Python 2.7 构建不会打印“\uFFFD”字符

py

我在 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]

下面是一些其他测试用例的实现说明:

Frgx4.gif

总结一下,所描述的打印行为有以下模式:

这取决于'\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 的行为完全相同。


阅读 5

收藏
2024-11-20

共1个答案

小能豆

我已经重现了您的问题,并且找到了适用于我的平台的解决方案:从您的***构建配置选项中删除该-u``cmd*标志。

我不确定为什么这样做有效,但这似乎是由于控制台解释包含多字节字符的未缓冲数据流而导致的不良交互。以下是我发现的情况:

  • -u选项将 Python 的输出切换为无缓冲
  • 这个问题并非特定于替换字符。我在使用其他字符(如“あ”(U+3042))时也遇到了类似的问题。
  • 其他编码也会出现类似的不良结果。设置"env": {"PYTHONIOENCODING": "utf-16be"}会导致print u'\u3042'输出0B

最后一个例子将编码设置为 UTF-16BE,说明了我认为发生了什么。由于输出未缓冲,因此控制台一次接收一个字节。因此它0x30首先接收字节。然后控制台确定这不是有效的 UTF-16BE,并决定改为回退到 ASCII,因此输出0。它当然会立即接收下一个字节,并按照相同的逻辑输出B

使用 UTF-8 编码时,控制台接收的字节不可能被解释为 ASCII,因此我相信控制台在正确解释无缓冲流方面做得稍微好一些,但它仍然遇到您的问题指出的困难。

2024-11-20