python curses addstr y-offset:unicode 的奇怪行为

python curses addstr y-offset: strange behavior with unicode

我在使用 python3 curses 和 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)

我可以很好地显示 unicode 字符,但是 addstr 的 y 偏移参数(我的代码中的 "offset")没有按预期运行;我的屏幕显示“わた你好”而不是“わたし你好”

事实上偏移量有非常奇怪的行为:

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

请注意,偏移量不是以字节为单位,因为字符是 3 字节的 unicode 字符:

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

我是 运行 python 4.8.3,curses.version 是 "b'2.2'"。

有谁知道这是怎么回事或如何调试它? 提前致谢。

您正在打印 3 个双角字符。也就是说,每个都占用两个单元格。

字符(或字节)中的字符串长度不一定与每个字符使用的单元格数相同.

Python curses 只是 ncurses 的薄层。

我希望第 1、3、5 行中的字符可以通过将一个字符放在这些双倍宽度字符的第二个单元格上来删除(ncurses 应该这样做...),但是那个细节可能是终端模拟器中的错误)。

根据 Thomas 的回复,我找到了 wcwidth 包 (https://pypi.python.org/pypi/wcwidth),它具有 return 单元格中 unicode 字符串长度的功能。

这是一个完整的工作示例:

#!/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)