Py学习  »  Python

Python Unicode编码混乱 :来自大洋彼岸的怨念

Python程序员 • 5 年前 • 386 次点击  

Unicode已经解决了很多问题。知晓ISO-8859-*CP437带来的混乱(当然对于非西方语言来说更糟糕)的人都可以证明这一点。当然,这些天他们正在做一项有的益工作——编码表情符号。


除表情符号之外,一切并不那么顺畅。今日Python 3带来的痛苦更是一言难尽。


Python决定将Unicode完全集成到语言中。听起来很不错吧?


但众多问题也随之而来。


例如,将带有智能引号的“播客”标题转为以ASCII编码会引致python错误,导致gPodder一款开源的播客接收器,采用PythonPyGTK开发,可帮助管理播客RSS供稿,并自动下载所需要的播客资料经常通过回溯退出。接着pexpect文档会告诉你用logfile = sys.stdout 来显示与虚拟终端的交互。就是这个在这些天引发了一个错误


文件名的处理可谓糟糕透顶。我最近处理了20年前当UTF-8还未成为文件名标准时的数据。这些文件名在UNIX上仍然有效,可以用tar命令进行压缩或解压。但当你试图将文件名以字符串的形式存储,编码错误便接踵而至。要想让Python程序正确地支持所有有效的Unix文件名,必须使用“bytes”而不是字符串,这可真够烦人的。所有Python程序正确的几率又能达到多少呢?我敢打赌,不会高的。


我最近正在处理mtree生成的数据,它使用八进制转义来处理文件名中的特殊字符。我认为这对于Python会很容易。结果

  • 许多错误的解答 ——对于某些值,你会得到一个编码错误。甚至那个页面上的正则表达式解决方案也不起作用。

  • 甚至存在更多错误的解答


第二个链接提到了一个未记录的函数—— codecs.escape_decode ,可正确解决这一问题。我最终不得不这样做:

而且,无论做什么,不要轻易写 if filetype=="file" ——这总被求值为False,因为 "file" 在逻辑运算时不同于 b"file" 。呃好吧,我承认,自己一开始没注意到,踩过这坑…

因此,如果希望在Python中正确处理Unix文件名,你必须:

  • 有一个完全避免Python字符串的处理路径。

  • 使用 sys.{stdin,stdout}.buffer 而不是简单的 sys.stdin/stdout 

  • 必须将文件名以字节形式提供给各种函数。详情请参阅 PEP 0471:“与os模块中的其他函数一样,scandir() 接受一个bytesstr类作为路径参数,并返回与路径类型相同的 DirEntry.name 和 DirEntry.path 属性。但是,强烈建议使用str类型,因为这样可以确保Unicode编码的文件名得到跨平台支持(在Windows上,Python 3.3开始,就已经不支持bytes编码的文件名了)。所以,如果你想跨平台,那就更糟了,因为不能在Unix上使用str也不能在Windows上使用bytes

 

更新:你想在命令行上接收文件名吗?我会把这个烂摊子交给你的。环境呢? 甚至都不清楚呢!


小编说两句:这事儿真不怪Python,题主这种“处理了20年前当UTF-8还未成为文件名标准时的数据”的任务,平时谁会碰到,这种任务当然需要题主对编码系统足够了解才能完成了......题主发发牢骚,别怨Python......


英文原文:http://changelog.complete.org/archives/9938-the-python-unicode-mess
译者:盈韬



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/GTIIwrTdQR
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/24752
 
386 次点击