我在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时,行为完全相同。
答案 0 :(得分:1)
编辑-1 - 使用带BOM的UTF8
在Windows的情况下,似乎BOM变得很重要。所以你需要使用下面的类型构建配置
{
"cmd": ["F:\\Python27-14\\python", "-u", "$file"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"env": {
"PYTHONIOENCODING": "utf_8_sig"
},
}
之后它也可以在Windows上正常使用
原始答案
我检查了这个问题,我在Python 2.7上使用Sublime文本时没有遇到同样的问题。唯一的变化是我必须将# -*- coding: utf-8 -*-
添加到文件的顶部。这似乎是这个问题中缺失的部分
# -*- coding: utf-8 -*-
print u'\u0061' # should be 'a'
print u'\ufffd' # should be '�' - the 'REPLACEMENT CHARACTER'
之后,逆转没有影响
您可以在
上查看有关此必需标头的更多详细信息Why declare unicode by string in python?
以下是上述链接的摘要
当您指定
# -*- coding: utf-8 -*-
时,您告诉Python您保存的源文件是utf-8
。 Python 2的默认值是ASCII(对于Python 3,它是utf-8
)。这只会影响解释器读取文件中字符的方式。
答案 1 :(得分:1)
我已经重现了您的问题,我发现无论如何都能在我的平台上运行解决方案:从-u
构建配置选项中删除cmd
标记。< / p>
我不是百分之百确定为什么会这样,但是由于控制台解释了包含多字节字符的无缓冲数据流,这似乎是一种糟糕的交互。这是我发现的:
-u
option将Python的输出切换为 unbuffered "env": {"PYTHONIOENCODING": "utf-16be"}
会导致print u'\u3042'
输出0B
。将编码设置为UTF-16BE的最后一个示例说明了我的想法。控制台一次接收一个字节,因为输出是无缓冲的。所以它首先接收0x30
字节。然后控制台确定这不是有效的UTF-16BE,而是决定回退到ASCII,从而输出0
。它的课程接收后面的下一个字节,并遵循相同的逻辑输出B
。
使用UTF-8编码,控制台接收的字节不可能被解释为ASCII,所以我相信控制台在正确解释无缓冲流方面做得稍微好一点,但它仍然遇到困难你的问题指出了。