4

我一直在阅读有关 Python 中 Curses 编程的教程,其中很多都提到了使用扩展字符的能力,例如画线符号。它们的字符数 > 255,curses 库知道如何以当前终端字体显示它们。

一些教程说你像这样使用它:

c = ACS_ULCORNER

...有人说你像这样使用它:

c = curses.ACS_ULCORNER

(这应该是一个盒子的左上角,就像一个垂直翻转的L)

无论如何,无论我使用哪种方法,都没有定义名称,因此程序会失败。我试过“import curses”和“from curses import *”,但都不管用。

Curses 的 window() 函数利用了这些字符,所以我什至尝试在我的盒子上四处寻找源代码,看看是如何做到的,但我在任何地方都找不到它。

4

3 回答 3

5

您必须将本地设置为全部,然后将输出编码为 utf-8,如下所示:

import curses
import locale

locale.setlocale(locale.LC_ALL, '')    # set your locale

scr = curses.initscr()
scr.clear()
scr.addstr(0, 0, u'\u3042'.encode('utf-8'))
scr.refresh()
# here implement simple code to wait for user input to quit
scr.endwin()

输出:あ</p>

于 2015-02-10T07:43:07.807 回答
4

来自curses/__init__.py

一些常量,尤其是ACS_* 那些常量,仅在调用后才添加到 C _curses模块的字典initscr()中。(SGI 的 curses 的某些版本在调用之前不会为这些常量定义值initscr() 。)这个包装函数调用底层 C initscr(),然后将常量从 _curses模块复制到 curses 包的字典。from curses import *如果您需要 ACS_*常量,请不要执行 ' '。

换句话说:

>>> import curses
>>> curses.ACS_ULCORNER
exception
>>> curses.initscr()
>>> curses.ACS_ULCORNER
>>> 4194412
于 2009-08-14T18:30:59.080 回答
4

我相信以下内容是适当相关的,将在此问题下发布。在这里,我将使用utfinfo.pl(另请参阅Super User)。

首先,对于标准的 ASCII 字符集,Unicode 码位和字节编码是一样的:

$ echo 'a' | perl utfinfo.pl 
Char: 'a' u: 97 [0x0061] b: 97 [0x61] n: LATIN SMALL LETTER A [Basic Latin]

所以我们可以在 Python 中做curses

window.addch('a')
window.border('a') 

...它按预期工作

但是,如果一个字符高于基本 ASCII,则存在差异,这些addch文档不一定会明确说明。首先,我可以这样做:

window.addch(curses.ACS_PI)
window.border(curses.ACS_PI)

...在这种情况下,在 my 中gnome-terminal,将呈现 Unicode 字符“π”。但是,如果您检查ACS_PI,您会看到它是一个整数,值为 4194427 (0x40007b); 所以以下也将呈现相同的字符(或评估者,字形?)'π':

window.addch(0x40007b)
window.border(0x40007b)

要查看发生了什么,我通过ncurses源代码查找,发现以下内容:

#define ACS_PI      NCURSES_ACS('{') /* Pi */  
#define NCURSES_ACS(c)  (acs_map[NCURSES_CAST(unsigned char,c)])
#define NCURSES_CAST(type,value) static_cast<type>(value)
#lib_acs.c: NCURSES_EXPORT_VAR(chtype *) _nc_acs_map(void): MyBuffer = typeCalloc(chtype, ACS_LEN);
#define typeCalloc(type,elts) (type *)calloc((elts),sizeof(type))
#./widechar/lib_wacs.c: { '{',  { '*',  0x03c0 }},  /* greek pi */

注意这里:

$ echo '{π' | perl utfinfo.pl 
Got 2 uchars
Char: '{' u: 123 [0x007B] b: 123 [0x7B] n: LEFT CURLY BRACKET [Basic Latin]
Char: 'π' u: 960 [0x03C0] b: 207,128 [0xCF,0x80] n: GREEK SMALL LETTER PI [Greek and Coptic]

...两者都与 4194427 (0x40007b) 的值无关ACS_PI

因此,当addch和/或border看到一个高于 ASCII 的字符(基本上是一个unsigned intunsigned char不是将它用作acs_map-ping 函数的查找索引(但是,即使它模拟 VT-100,它最终也会返回 Unicode 代码点)。这就是为什么下面的规范:

window.addch('π') 
window.border('π') 

argument 1 or 3 must be a ch or an int在 Python 2.7 中使用;将失败 而在 Python 3.2 中只会呈现一个空格而不是一个字符。当我们指定'π'. 我们实际上已经指定了 UTF-8 编码 [0xCF,0x80] - 但即使我们指定了 Unicode 代码点:

window.addch(0x03C0) 
window.border0x03C0) 

...它只是在 Python 2.7 和 3.2 中不呈现任何内容(空间)。

话虽如此 - 该函数addstr 确实接受 UTF-8 编码的字符串,并且工作正常:

window.addstr('π')

...但是对于边界 - 因为border()显然以相同的方式处理字符addch()- 我们显然不走运,对于任何没有明确指定为ACS常量的东西(而且它们中的数量也不多)。

希望这对某人有帮助,
干杯!

于 2013-05-15T12:02:49.123 回答