Estoy teniendo problemas con las maldiciones python3 y unicode:

#!/usr/bin/env python3
import curses
import locale

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

def doStuff(stdscr):
  offset = 3
  stdscr.addstr(0, 0, "わたし")
  stdscr.addstr(0, offset, 'hello', curses.A_BOLD)
  stdscr.getch() # pauses until a key's hit

curses.wrapper(doStuff)

Puedo mostrar caracteres Unicode muy bien, pero el argumento y-offset de addedtr ("offset" en mi código) no funciona como se esperaba; mi pantalla muestra "わ た hola" en lugar de "わ た し hola"

De hecho, el desplazamiento tiene un comportamiento muy extraño:

- 0:hello
- 1:わhello
- 2:わhello
- 3:わたhello
- 4:わたhello
- 5:わたしhello
- 6:わたしhello
- 7:わたし hello
- 8:わたし  hello
- 9:わたし   hello

Tenga en cuenta que el desplazamiento no está en bytes, ya que los caracteres son caracteres Unicode de 3 bytes:

>>>len("わ".encode('utf-8'))
3
>>> len("わ")
1

Estoy ejecutando Python 4.8.3 y curses.version es "b'2.2 '".

¿Alguien sabe qué está pasando o cómo depurar esto? Gracias por adelantado.

0
B. Thompson 15 dic. 2016 a las 02:00

2 respuestas

La mejor respuesta

Está imprimiendo 3 caracteres de doble ancho. Es decir, cada uno de ellos ocupa dos celdas.

La longitud de la cadena en caracteres (o bytes ) no es necesariamente la misma que la cantidad de celdas utilizadas para cada carácter.

Python curses es solo una capa delgada sobre ncurses.

Esperaría que los caracteres en las líneas 1, 3, 5 se borren colocando un carácter en la segunda celda de esos caracteres de doble ancho (se supone que ncurses hace esto ...), pero ese detalle podría ser un error en el emulador de terminal).

0
Thomas Dickey 15 dic. 2016 a las 02:38

Según la respuesta de Thomas, encontré el paquete wcwidth (https://pypi.python.org/pypi / wcwidth) que tiene una función para devolver la longitud de una cadena Unicode en las celdas.

Aquí hay un ejemplo de trabajo completo:

#!/usr/bin/env python3
import curses
import locale
from wcwidth import wcswidth

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

def doStuff(stdscr):
  foo = "わたし"
  offset = wcswidth(foo)
  stdscr.addstr(0, 0, foo)
  stdscr.addstr(0, offset, 'hello', curses.A_BOLD)
  stdscr.getch() # pauses until a key's hit

curses.wrapper(doStuff)
0
B. Thompson 15 dic. 2016 a las 17:04