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

时间:2016-12-14 23:00:27

标签: python-3.x unicode curses python-curses

我遇到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(" offset"在我的代码中)的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'"。

有谁知道发生了什么或如何调试这个? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

您正在打印3个双倍宽度的字符。也就是说,每个人占用两个单元格。

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

Python curses只是ncurses的一个薄层。

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

答案 1 :(得分:0)

根据Thomas的回复,我找到了wcwidth包(https://pypi.python.org/pypi/wcwidth),它具有返回单元格中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)