Comment puis-je utiliser des caractères étendus dans Python maudit bibliothèque?
Question
J'ai lu des tutoriels sur la programmation Curses en Python, et beaucoup se réfèrent à une capacité à utiliser des caractères étendus, tels que les symboles de tracé. Ils sont des personnages> 255, et la bibliothèque curses sait comment les afficher dans la police terminal.
Certains comme les tutoriels que vous utilisez 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 d'une boîte, comme un L renversé à la verticale)
De toute façon, quelle que soit la méthode que j'utilise, le nom n'est pas défini et le programme échoue donc. J'ai essayé « malédictions à l'importation » et « des malédictions import * », et ni travaux.
Fonction fenêtre () de Curses utilise ces personnages, donc je même essayé de fouiller sur ma boîte pour la source pour voir comment il fait, mais je ne peux pas le trouver nulle part.
La solution
De curses/__init__.py
:
Certaines constantes, notamment le
ACS_*
chers, ne sont ajoutés à l'extrémité C Le dictionnaire du module_curses
aprèsinitscr()
est appelé. (Certaines versions des malédictions de SGI ne définissent pas les valeurs pour les constantes jusqu'à ce queinitscr()
a été appelé.) Cette enveloppe fonction appelle la C sous-jacenteinitscr()
, puis copie les les constantes de la module_curses
au dictionnaire du paquet malédictions. Ne pas faire «from curses import *
» si vous allez avoir besoin de la constantes deACS_*
.
En d'autres termes:
>>> import curses
>>> curses.ACS_ULCORNER
exception
>>> curses.initscr()
>>> curses.ACS_ULCORNER
>>> 4194412
Autres conseils
Je crois être affiché sous cette question ci-dessous l'est appropriée liée,. Ici, je vais utiliser utfinfo.pl ( voir aussi super User ).
Tout d'abord, pour ensemble standard de caractères ASCII, le point de code Unicode et l'encodage d'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]
Nous pouvons faire dans le curses
Python:
window.addch('a')
window.border('a')
... et cela fonctionne comme prévu
Cependant, si un personnage est au-dessus ASCII de base, alors il y a des différences, qui addch
docs ne font pas nécessairement explicites. Tout d'abord, je peux le 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 que c'est un nombre entier, avec une valeur de 4.194.427 (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 la source à travers rassemblés de ncurses
de, 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 */
Note 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 4194427 (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) utiliser ce numéro pas comme point de code Unicode , ou comme représentation UTF-8 octets codés - mais au contraire, ils l'utilisent comme un index de consultation pour la fonction acs_map
-ping (qui en fin de compte, cependant, serait retourner 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 en Python 3.2 rendrait simplement un espace au lieu d'un caractère. Lorsque nous précisons 'π'
. 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 addstr
Finalité acceptent UTF-8 chaînes codées, 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()
ne - nous sommes apparemment pas de chance, quoi que ce soit pas explicitement spécifié comme une constante de ACS
(et il n'y a pas que beaucoup d'entre eux, que ce soit) .
L'espoir que cela aide quelqu'un,
Vive!
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: あ