Como faço para usar estendido caracteres em Python amaldiçoa biblioteca?
Pergunta
Estive lendo tutoriais sobre Maldições programação em Python, e muitos se referem a capacidade de utilizar caracteres estendidos, como símbolos de desenho de linha. Eles são personagens> 255, e as maldições biblioteca sabe como exibi-los na fonte terminal atual.
Alguns dos tutoriais dizer que você usá-lo como este:
c = ACS_ULCORNER
... e alguns dizem que você usá-lo como este:
c = curses.ACS_ULCORNER
(que é suposto ser o canto superior esquerdo de uma caixa, como um L invertido verticalmente)
De qualquer forma, independentemente de qual uso do método I, o nome não está definido e o programa falhar assim. Eu tentei "maldições de importação" e "de maldições import *", e nem obras.
janela Curses' () função faz uso desses personagens, então eu ainda tentou picar ao redor na minha caixa para a fonte para ver como it faz isso, mas eu não posso encontrá-lo em qualquer lugar.
Solução
De curses/__init__.py
:
Algumas constantes, mais notavelmente o
ACS_*
queridos, só são adicionados ao C dicionário do módulo_curses
apósinitscr()
é chamado. (Algumas versões de maldições da SGI não definem valores para essas constantes atéinitscr()
foi chamado.) Este invólucro chamadas de função do C subjacenteinitscr()
, e, em seguida, as cópias As constantes da módulo_curses
ao dicionário do pacote de maldições. Não faça 'from curses import *
' se você vai precisar do constantesACS_*
.
Em outras palavras:
>>> import curses
>>> curses.ACS_ULCORNER
exception
>>> curses.initscr()
>>> curses.ACS_ULCORNER
>>> 4194412
Outras dicas
Eu acredito que o está adequadamente relacionada, a ser publicado sob esta pergunta abaixo. Aqui eu vou estar usando utfinfo.pl ( ver também em Super User ).
Em primeiro lugar, para o conjunto de caracteres ASCII padrão, o ponto de código Unicode e a codificação byte é o mesmo:
$ echo 'a' | perl utfinfo.pl
Char: 'a' u: 97 [0x0061] b: 97 [0x61] n: LATIN SMALL LETTER A [Basic Latin]
Assim, podemos fazer em curses
do Python:
window.addch('a')
window.border('a')
... e funciona como pretendido
No entanto, se um personagem está acima ASCII básico, em seguida, há diferenças, que docs addch
não fazem necessariamente explícita. Em primeiro lugar, eu posso fazer:
window.addch(curses.ACS_PI)
window.border(curses.ACS_PI)
... caso em que, na minha gnome-terminal
, o caráter Unicode 'p' é processado. No entanto, se você inspecionar ACS_PI
, você verá que é um número inteiro, com um valor de 4194427 (0x40007b); assim também o seguinte irá processar o mesmo personagem 'p' (ou avaliador, glifo?):
window.addch(0x40007b)
window.border(0x40007b)
Para ver o que está acontecendo, eu grepped através da fonte ncurses
, e encontrou o seguinte:
#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 aqui:
$ 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]
... nenhum dos quais se relaciona com o valor de 4194427 (0x40007b) para ACS_PI
.
Assim, quando addch
e / ou border
ver um caractere acima ASCII (basicamente um unsigned int
, em oposição a unsigned char
), que (pelo menos neste exemplo) uso esse número acs_map
-ping (que em última análise, no entanto, se retornar o ponto de código Unicode, mesmo que emula VT-100). Por isso, a seguinte especificação:
window.addch('π')
window.border('π')
falhará em Python 2.7 com argument 1 or 3 must be a ch or an int
; e em Python 3.2 tornaria simplesmente um espaço em vez de um personagem. Quando especificar 'π'
. nós realmente especificou a codificação UTF-8 [0xCF, 0x80] - mas mesmo que especificar o ponto de código Unicode:
window.addch(0x03C0)
window.border0x03C0)
... ele simplesmente torna nada (espaço) em ambos os Python 2.7 e 3.2.
Dito isto - a função addstr
não aceitar cadeias de codificação UTF-8, e funciona bem:
window.addstr('π')
... mas para as fronteiras - desde border()
aparentemente lida com caracteres da mesma forma addch()
faz - estamos aparentemente fora de sorte, para qualquer coisa não explicitamente especificado como uma constante ACS
(e não há que muitos deles, qualquer um) .
Espero que isso ajude alguém,
Felicidades!
Você tem que definir o local para tudo, em seguida, codificar a sua saída como utf-8 como segue:
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()
saída: ?