无法在OSX终端和ncurses上显示警告标志

时间:2014-11-13 22:38:19

标签: python macos unicode ncurses

OSX 10.6.8上的这个简单程序,python 3.4,Terminal.app和字体Menlo打印出三个unicode字符:一个笑脸,一个警告标志和一个放射性符号,或者我应该说应该打印,因为事实上我只得到第一个和最后一个。警告标志不存在。

from curses import wrapper

def main(stdscr):
    # Clear screen
    stdscr.clear()

    for i in range(1, 11):
        stdscr.addstr(i, 0, '\u263a \u26a0 \u2622'.encode("utf-8"))

    stdscr.refresh()
    stdscr.getkey()

wrapper(main)

此外,如果我打开字体书,显然Menlo确实有警告标志的字形,但最让我困惑的是,如果我去编辑 - >特殊字符,选择警告标志,然后单击插入,我在命令提示符处得到警告标志。另外使用print()显示警告标志。

发生了什么?

编辑:显然它是OSX libc库中的一个错误。见这里

How to get ncurses to output astral plane unicode characters

我尝试编译小程序来获取wcinfo

sbo@sbos-macbook:~$ ./wcinfo 26a0
Code 26A0: width -1 
sbo@sbos-macbook:~$ ./wcinfo 263a
Code 263A: width 1 punct graph print 

因此,对于警告标志,我们得到-1,这意味着不可打印的字符。所以,绝对是一个OSX问题,也是一个基本问题。

2 个答案:

答案 0 :(得分:1)

当我使用Lucida Console作为字体在我的Mac OS X 10.10(Yosemite)终端上运行它时,我得到如下所示的输出:

$ printf "%s\n" u+263a u+0020 u+26a0 u+0020 u+2622 | unicode-utf8
☺ ⚠ ☢
$  printf "%s\n" u+263a u+0020 u+26a0 u+0020 u+2622 | unicode-utf8 | odx
0x0000: E2 98 BA 20 E2 9A A0 20 E2 98 A2 0A               ... ... ....
0x000C:
$ printf "%s\n" u+263a u+0020 u+26a0 u+0020 u+2622 | unicode-utf8 | utf8-unicode
(standard input):
0xE2 0x98 0xBA = U+263A
0x20 = U+0020
0xE2 0x9A 0xA0 = U+26A0
0x20 = U+0020
0xE2 0x98 0xA2 = U+2622
0x0A = U+000A
$

程序unicode-utf8utf8-unicodeodx都是家酿程序(Unicode不是特别优雅),但它们允许我使用Unicode进行分析工作。并且,至少在我的计算机上,所有三个符号都显示出来。当它们没有被空格分隔时,三角形和辐射符号在屏幕上重叠(与浏览器不同),这就是我添加空格的原因:

☺⚠☢

因此,我建议您仔细查看您显示的脚本的输出。您可能会看到编码问题,或者curses库可能无法正确识别UTF-8或...

当我使用Python 2运行时,我得到:

\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622
\u263a \u26a0 \u2622

当我使用Python 3运行时,我得到:

☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢
☺   ☢

这意味着我可以重现这个问题,但它似乎是Python中的一个问题而不是终端。

我跑了:

$ python3 so.26919799.py > py3.output
$ odx py3.output

输出的相关部分是:

0x1D60: 20 20 20 20 20 20 20 1B 5B 36 35 3B 31 48 20 20          .[65;1H  
0x1D70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                   
* (5)
0x1DD0: 20 20 20 20 20 20 20 20 20 20 20 08 20 08 1B 5B              . ..[
0x1DE0: 34 68 20 1B 5B 34 6C 1B 5B 48 0A E2 98 BA 20 20   4h .[4l.[H....  
0x1DF0: 20 E2 98 A2 0D 0A E2 98 BA 20 20 20 E2 98 A2 0D    ........   ....
0x1E00: 0A E2 98 BA 20 20 20 E2 98 A2 0D 0A E2 98 BA 20   ....   ........ 
0x1E10: 20 20 E2 98 A2 0D 0A E2 98 BA 20 20 20 E2 98 A2     ........   ...
0x1E20: 0D 0A E2 98 BA 20 20 20 E2 98 A2 0D 0A E2 98 BA   .....   ........
0x1E30: 20 20 20 E2 98 A2 0D 0A E2 98 BA 20 20 20 E2 98      ........   ..
0x1E40: A2 0D 0A E2 98 BA 20 20 20 E2 98 A2 0D 0A E2 98   ......   .......
0x1E50: BA 20 20 20 E2 98 A2 1B 5B 3F 31 6C 1B 3E 1B 5B   .   ....[?1l.>.[
0x1E60: 6D 0D 1B 5B 35 34 42 1B 5B 4B 1B 5B 36 35 3B 31   m..[54B.[K.[65;1
0x1E70: 48 1B 5B 32 4A 1B 5B 3F 34 37 6C 1B 38 0D 1B 5B   H.[2J.[?47l.8..[
0x1E80: 3F 31 6C 1B 3E                                    ?1l.>
0x1E85:

0x1D60:表示文件中的字节偏移量。我的终端窗口是110宽,65深,所以输出产生了很多空白。 * (5)行表示另外5行16个空格。然后你可以看到一些包含字节E2 98 BA和E2 98 A2的数据,但是在它们之间有三个空白,而不是你期望的E2 98 A0。因此,Python 3错误地处理了警告符号的翻译。

答案 1 :(得分:1)

在3.4.2 Win 7上,使用Lucida Console在Idle的tkinter文本小部件中打印警告标志。此外,Python正确地对utf-8进行编码和解码。这与“python无法正确编码\ u26a0(警告标志)到utf-8”相反,Stefano将其发布到py-dev。

>>> s='\u26a0'
>>> s
'⚠'  # up-pointing triangle /_\ with ! inside
>>> b=s.encode('utf-8')
>>> b
b'\xe2\x9a\xa0'  # E2 9A A0 is what Jonathan said is correct.
>>> b.decode('utf-8')
'⚠'

OSX上stdscr是一个额外的内置名称吗?或者是否缺少定义它的代码?