【问题标题】:Unexpected Blank lines in python output to Windows consolepython输出到Windows控制台中的意外空行
【发布时间】:2016-02-04 14:35:01
【问题描述】:

我有一个打印出目录结构的小程序。 它工作正常,除非目录名称包含德语变音符号。 在这种情况下,int 在目录行之后打印一个空行。

我在 Windows 7 64 位上运行 Python 3.50。

此代码...

class dm():
...
    def print(self, rootdir=None, depth=0):

    if rootdir is None:
        rootdir = self.initialdir

    if rootdir in self.dirtree:
        print('{}{} ({} files)'.format('   '*depth, 
                                    rootdir, 
                                    len(self.dirtree[rootdir]['files'])))
        for _dir in self.dirtree[rootdir]['dirs']:
            self.print(os.path.join(rootdir, _dir), depth+1)
    else:
        pass

...产生以下输出:

B:\scratch (11 files)
   B:\scratch\Test1 (3 files)
   B:\scratch\Test1 - Kopie (0 files)
   B:\scratch\Test1 - Übel (0 files)

   B:\scratch\Test2 (3 files)
      B:\scratch\Test2\Test21 (0 files)

代码页设置为 65001 时也是如此。如果我将代码页更改为例如850 然后空白行消失,但“Ü”当然没有正确打印。

结构 self.dirtree 是列表的字典,用 os.walk 解析,看起来没问题。

Python 还是 Windows?有什么建议吗?
马文

【问题讨论】:

    标签: windows python-3.x


    【解决方案1】:

    使用代码页 65001 (UTF-8) 时有几个错误 - 所有这些错误都是由 Windows 控制台(即 conhost.exe)造成的,而不是 Python。最好的解决方案是避免这个错误的代码页,而是使用宽字符 API,例如通过加载 win_unicode_console

    您遇到了在 Windows 10 之前使用的旧控制台中存在的错误。(如果您选择“使用旧控制台”选项,它在 Windows 10 中仍然可用。)控制台解码 UTF-8 缓冲区到 UTF-16 并报告它将 b'\xc3\x9c'(即编码为 UTF-8 的 "Ü")作为一个字符写入,但它应该报告它写入的 bytes 的数量,即是两个。 Python 的缓冲sys.stdout 看到显然没有写入一个字节,因此它尽职尽责地再次写入该行的最后一个字节,即b'\n'。这就是为什么你会得到一个额外的换行符。如果写入的缓冲区包含许多非 ASCII 字符,尤其是 U+07FF 以上的代码被编码为三个 UTF-8 字节,结果可能会更糟。


    如果您尝试将 "Ü" 粘贴到交互式 REPL 中,则会出现更严重的错误。即使在 Windows 10 中仍然存在此错误。在这种情况下,进程正在读取编码为 UTF-8 的控制台的宽字符 (UTF-16) 输入缓冲区。控制台通过WideCharToMultiByte 使用缓冲区进行转换,该缓冲区假定一个Unicode 字符是目标代码页中的一个字节。但这对于 UTF-8 来说是完全错误的,其中一个 UTF-16 代码可能映射到多达三个字节。在这种情况下,它是两个字节,控制台只在翻译缓冲区中分配一个字节。所以WideCharToMultiByte 失败了,但是控制台会尝试增加翻译缓冲区的大小吗?不,它会失败吗?不,它实际上返回它“成功”读取了 0 个字节。到 Python 的 REPL 信号 EOF(文件结束),所以解释器就像你在提示符处输入 Ctrl+Z 一样退出。

    【讨论】:

    • 感谢您详尽的回答 eryksun。幸运的是,我的代码不依赖于打印(仅用于调试)。不过,我会用 win_unicode_console 试试你的建议。马文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2020-04-24
    • 1970-01-01
    相关资源
    最近更新 更多