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.{stdin,stdout}.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
译者:盈韬
来源:Python程序员
《Linux云计算及运维架构师高薪实战班》2018年11月26日即将开课中,
120天冲击Linux运维年薪30万