在尝试将 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)
这是它的Gist 链接。
问题是当我按下è
键(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()
为 127 以上的字符返回不正确的 ASCII 码以及为什么真正的 ASCII 码与 curses 返回的码之间的差异是 64,我会很高兴。
非常感谢您提前。