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

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

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

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

但众多问题也随之而来。

例如,将带有智能引号的“播客”标题转为以ASCII编码会引致python错误,导致gPodder(一款开源的播客接收器,采用Python和PyGTK开发,可帮助管理播客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..buffer而不是简单的sys.stdin/stdout。

必须将文件名以字节形式提供给各种函数。详情请参阅PEP 0471:“与os模块中的其他函数一样,scandir()接受一个bytes或str类作为路径参数,并返回与路径类型相同的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

译者:盈韬

*声明:推送内容及图片来源于网络,部分内容会有所改动,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

- END -

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181012B25KZI00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券