2009-08-14 8 views
4

J'ai lu des tutoriels sur la programmation des malédictions en Python, et beaucoup se réfèrent à la possibilité d'utiliser des caractères étendus, tels que des symboles de dessin au trait. Ce sont des caractères> 255, et la bibliothèque de curses sait comment les afficher dans la police de terminal courante.Comment utiliser des caractères étendus dans la bibliothèque curses de Python?

Certains des tutoriels vous disent l'utiliser comme ceci:

c = ACS_ULCORNER 

... et certains disent que vous l'utilisez comme ceci:

c = curses.ACS_ULCORNER 

(C'est censé être le coin supérieur gauche coin d'une boîte, comme un L renversé verticalement)

Quoi qu'il en soit, quelle que soit la méthode que j'utilise, le nom n'est pas défini et le programme échoue donc. J'ai essayé "importer des malédictions" et "from curses import *", et ni ne fonctionne.

La fonction window() de Curses utilise ces caractères, donc j'ai même essayé de fouiller sur ma boîte pour que la source le voit, mais je ne le trouve nulle part.

Répondre

3

De curses/__init__.py:

Certaines constantes, notamment les ACS_* les, ne sont ajoutés au dictionnaire du module C _curses après initscr() est appelé. (Certaines versions des malédictions de SGI ne définissent pas les valeurs pour les constantes jusqu'à ce que initscr() a été appelé.) Cette enveloppe fonction appelle la C initscr() sous-jacents, puis copie les constantes du module _curses à celui du paquet malédictions dictionnaire. Ne faites pas 'from curses import *' si vous avez besoin des constantes ACS_*.

En d'autres termes:

>>> import curses 
>>> curses.ACS_ULCORNER 
exception 
>>> curses.initscr() 
>>> curses.ACS_ULCORNER 
>>> 4194412 
+1

Merci pour cela; pour vider les ACS disponibles à partir de 'curses' de Python, on pourrait utiliser:' python -c 'importer pprint, inspecter, maudire; curses.initscr(); outstr = pprint.pformat (inspect.getmembers (malédictions)); curses.endwin(); impression (outstr) '| grep ACS'. À votre santé! – sdaau

4

Je crois que le est lié de façon appropriée ci-dessous, être affiché sous cette question. Ici, je vais utiliser utfinfo.pl (voir également sur Super User).

tout d'abord, pour ensemble standard de caractères ASCII, le point de code Unicode et l'encodage des octets est le même:

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

donc nous pouvons faire en Python curses:

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

.. et cela fonctionne comme prévu

Cependant, si un caractère est au-dessus de l'ASCII basique, alors il y a des différences, que addch docs ne rendent pas nécessairement explicites. Tout d'abord, je peux faire:

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

... dans ce cas, dans mon gnome-terminal, le caractère Unicode 'tc' est rendu.Toutefois, si vous inspectez ACS_PI, vous verrez qu'il s'agit d'un nombre entier, avec une valeur de 4194427 (0x40007b); de sorte que le suivant sera également rendre le même caractère « π » (ou noteur, glyphe?):

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

Pour voir ce qui se passe, je rassemblés de par la source ncurses, et a trouvé ce qui suit:

#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 */ 

Remarque ici:

$ 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] 

... ni qui se rapporte à la valeur de 4.194.427 (0x40007b) pour ACS_PI.

Ainsi, lorsque addch et/ou border voir un caractère au-dessus ASCII (essentiellement un unsigned int, par opposition à unsigned char), ils (au moins dans ce cas) utilisent ce numéro pas comme point de code Unicode, ou UTF -8 représentation encodée octets - mais à la place, ils l'utilisent comme un index de recherche pour acs_map -ping fonction (qui finalement, cependant, retournerait le point de code Unicode, même si elle émule VT-100). Voilà pourquoi la spécification suivante:

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

échouera en Python 2.7 avec argument 1 or 3 must be a ch or an int; et dans Python 3.2 rendrait simplement un espace au lieu d'un caractère. Lorsque nous spécifions 'π'. nous avons effectivement spécifié l'encodage UTF-8 [0xCF, 0x80] - mais même si nous précisons le point de code Unicode:

window.addch(0x03C0) 
window.border0x03C0) 

... il rend tout simplement rien (espace) dans les deux Python 2.7 et 3.2.

Cela étant dit - la fonction addstrne acceptent les chaînes codées UTF-8, et fonctionne très bien:

window.addstr('π') 

... mais pour les frontières - depuis border() poignées apparemment personnages de la même manière addch()-t - Nous n'avons apparemment pas de chance, pour tout ce qui n'est pas explicitement spécifié comme une constante ACS (et il n'y en a pas beaucoup non plus).

Espérons que cela aide quelqu'un,
Cheers!

3

vous devez définir votre local à tous, puis encoder votre sortie en utf-8 comme suit:

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() 

sortie: あ