Используйте кодировку utf-8 с рамкой curses и python3 - PullRequest
2 голосов
/ 22 февраля 2020

Я не могу использовать в моей программе python3 curses. Это часть моего кода:

    import curses
    import locale

    locale.setlocale(locale.LC_ALL)
    locale.getpreferredencoding()
    stdscr = curses.initscr()
    caracter = str('█')
    stdscr.border(
            caracter, caracter, caracter, caracter, 
            caracter, caracter, caracter, caracter)

Я получаю эту ошибку

OverflowError: байт не помещается в chtype

Я могу однако используйте функцию addstr для написания некоторого кода utf-8, подобного этому

    stdscr.addstr(0, 0, "█")

Спасибо за вашу помощь.

1 Ответ

2 голосов
/ 24 февраля 2020

Проблема в том, что пакет Python curses - это просто оболочка над библиотекой ncurses C. А в ncurses (https://linux.die.net/man/3/ncurses) символ представлен как chtype, (данные символов и атрибутов) , где символ является типом C char, который просто байт в распространенных системах.

Базовая функция border ожидает, что каждый символ границы будет одним байтом, в то время как 'FULL BLOCK', который вы пытаетесь использовать, является символ Unicode U + 2588 или строка байтов UTF-8 b'\xe2\x96\x88'. Вот причина сообщения об ошибке: вы пытаетесь сохранить 3-байтовую последовательность в одну байтовую переменную.

Она отлично работает для addstr, потому что эта функция ожидает строку и принимает 3-байтовую последовательность. Но он порвется с addch, который ожидает одну строку.

Иными словами, модуль curses не будет принимать многобайтовые последовательности UTF-8, кроме случаев, когда он ожидает строки.

Возможные обходные пути:

  • рекомендуемый способ использования базовой библиотеки ncurses и модуля curses Python - найти однобайтовую кодировку, соответствующую вашим требованиям. Latin1 (ISO-8859-1) является даже значением по умолчанию для ncurses, но другие кодировки могут лучше удовлетворить ваши потребности.
  • найти (или написать) оболочку Python вокруг ncursesw. Это вариант ncurses с использованием широких (16 бит) символов. Он с радостью принял бы 0x2588 в качестве символьного значения или, в более общем случае, любой символ, имеющий только 16-битную кодовую точку, которая является просто многоязычной плоскостью Unicode Basi c. К сожалению, я не знаю ни одного.
...