Python curses печатает два символа при добавлении строки в кодировке utf-8
Я столкнулся с очень странной проблемой при попытке напечатать строки в кодировке UTF-8 в окне curses. Вот код, я расскажу о точной проблеме и вещах, которые я попробовал ниже.
# coding=UTF-8
import curses
import locale
import time
locale.setlocale(locale.LC_ALL, '')
code = locale.getpreferredencoding()
class AddCharCommand(object):
def __init__(self, window, line_start, y, x, character):
"""
Command class for adding the specified character, to the specified
window, at the specified coordinates.
"""
self.window = window
self.line_start = line_start
self.x = x
self.y = y
self.character = character
def write(self):
if self.character > 127:
# curses somehow returns a keycode that is 64 lower than what it
# should be, this takes care of the problem.
self.character += 64
self.string = unichr(self.character).encode(code)
self.window.addstr(self.y, self.x, self.string)
else:
self.window.addch(self.y, self.x, self.character)
def delete(self):
"""
Erase characters usually print two characters to the curses window.
As such both the character at these coordinates and the one next to it
(that is the one self.x + 1) must be replaced with the a blank space.
Move to cursor the original coordinates when done.
"""
for i in xrange(2):
self.window.addch(self.y, self.x + i, ord(' '))
self.window.move(self.y, self.x)
def main(screen):
maxy, maxx = screen.getmaxyx()
q = 0
commands = list()
x = 0
erase = ord(curses.erasechar())
while q != 27:
q = screen.getch()
if q == erase:
command = commands.pop(-1).delete()
x -= 1
continue
command = AddCharCommand(screen, 0, maxy/2, x, q)
commands.append(command)
command.write()
x += 1
curses.wrapper(main)
Проблема в том, что когда я нажимаю è
ключ (который имеет код ASCII 232), он не печатает только этот символ. Вместо этого строка ăè
печатается по заданным координатам. Я пытался использовать self.window.addstr(self.x, self.y, self.string[1])
но это только привело к печатанию тарабарщины.
Затем я запустил приглашение Python, чтобы увидеть возвращаемое значение unichr(232).encode('utf-8')
и это действительно строка длины 2.
Очень неожиданное поведение заключается в том, что, если я положу в screen.addstr(4, 4, unichr(232).encode(code))
в main
он будет правильно отображать è
характер, и только этот персонаж. Это также тот случай, если я сделаю write
метод AddCharCommand
класс для печати è
характер, несмотря ни на что.
Проблема, конечно, не ограничивается è
только это в значительной степени относится ко всем символам расширенного ASCII.
Я знаю, что расширенный ASCII с проклятиями немного ненадежен, но я просто не могу понять это поведение вообще. Для меня не имеет никакого смысла (для меня), что код работает должным образом, если я жестко кодирую код ASCII, но он добавляет другой символ, если я этого не делаю.
Я осмотрелся и прочитал довольно много материала о проклятиях, но я не смог найти решение этой проблемы. Я был бы очень признателен за любую помощь по этому вопросу, это сводит меня с ума.
Может быть, немного менее важно, но я был бы рад, если бы кто-то мог объяснить мне, почему screen.getch()
возвращает неверный код ASCII для символов выше 127 и почему разница между реальным кодом ASCII и кодом, возвращаемым curses, составляет 64.
Заранее большое спасибо.