我有一个打印出直接结构的小程序。 除非目标名称包含德语变音字符,否则它可以正常工作。 在这种情况下,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?有什么建议吗? 马文
答案 0 :(得分:0)
使用代码页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个字节。对于发出EOF
(文件末尾)信号的Python的REPL,解释器就像你在提示符下输入Ctrl+Z
一样退出。