Como faço para usar estendido caracteres em Python amaldiçoa biblioteca?

StackOverflow https://stackoverflow.com/questions/1279341

  •  16-09-2019
  •  | 
  •  

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.

Foi útil?

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ós initscr() é 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 subjacente initscr(), 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 constantes ACS_*.

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 não como Unicode ponto de código , ou como UTF-8 codificado bytes representação - mas em vez disso, eles usam isso como um índice de look-up para a função 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: ?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top