Python处理非法文件名导致的UnicodeEncodeError
本文介绍Python在打印包含非UTF-8编码字符的文件名时,为何会抛出UnicodeEncodeError异常。通过示例展示了利用surrogateescape错误处理器优雅处理操作系统API返回的非法文件名编码问题,避免程序崩溃。
Python打印非法文件名引发的错误
问题
当程序尝试获取目录下的文件名列表并直接打印时,可能会遭遇UnicodeEncodeError异常,伴随提示“surrogates not allowed”(不允许代理对)。
处理文件名编码问题的解决方案
解决方案
为避免打印未知文件名时出错,可采用特定处理方法。
def bad_filename(filename):
return repr(filename)[1:-1]
try:
print(filename)
except UnicodeEncodeError:
print(bad_filename(filename))
若代码仅用于操作文件名或将其传递给open()等函数,通常不会出现问题。主要麻烦出现在需要输出文件名至屏幕或日志文件时。例如,直接打印上述文件名列表会导致程序崩溃。
>>> for name in files:
... print(name)
...
spam.py
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\udce4' in
position 1: surrogates not allowed
>>>
>>> for name in files:
... try:
... print(name)
... except UnicodeEncodeError:
... print(bad_filename(name))
...
spam.py
b\udce4d.txt
foo.txt
>>>
bad_filename()函数的具体处理方式由开发者决定。另一种选择是对文件名进行重新编码,参考以下示例。
def bad_filename(filename):
temp = filename.encode(sys.getfilesystemencoding(), errors='surrogateescape')
return temp.decode('latin-1')
surrogateescape编码机制解析
译者注:
surrogateescape是Python在大多数面向操作系统的API中采用的错误处理器。它能优雅地处理由操作系统提供的数据的编码问题。在解码出错时,会将出错字节存储到一个很少被使用到的Unicode编码范围内。在编码时,将那些隐藏值又还原回原先解码失败的字节序列。它不仅对于OS API非常有用,也能很容易的处理其他情况下的编码错误。
使用此版本产生的输出如下:
>>> for name in files:
... try:
... print(name)
... except UnicodeEncodeError:
... print(bad_filename(name))
...
spam.py
bäd.txt
foo.txt
>>>
本节主题可能被大部分读者忽略,但若编写依赖文件名和文件系统的关键任务程序,必须考虑此问题。否则,可能会在周末被紧急叫回办公室调试令人费解的错误。
以上就是Python打印不合法的文件名的详细内容,更多关于Python 打印文件名的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













