jac*_*ack 8 python unicode filenames
在执行以下代码时,它抛出"UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xc2:序号不在范围内(128)":
filename = 'Spywaj.ttf'
print repr(filename)
>> 'Sp\xc2\x88ywaj.ttf'
filepath = os.path.join('/dirname', filename)
Run Code Online (Sandbox Code Playgroud)
但该文件有效并存在于磁盘上.文件名是从"unzip -l"命令中提取的.如何加入这样的文件名?
操作系统和文件系统
Filesystem: ext3 relatime,errors=remount-ro 0 0
Locale: en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)
Alex的建议 os.path.join现在可以工作,但我仍然无法使用它加入的文件名访问磁盘上的文件.
filename = filename.decode('utf-8')
filepath = os.path.join('/dirname', filename)
print filepath
>> /dirname/u'Sp\xc2\x88ywaj.ttf'
print os.path.isfile(filepath)
>> False
new_filepath = filepath.encode('Latin-1').encode('utf-8')
print new_filepath
>> /dirname/u'Sp\xc2\x88ywaj.ttf'
print type(filepath)
>> <type 'unicode'>
print os.path.isfile(new_filepath)
>> False
valid_filepath = glob.glob('/dirname/*.ttf')[0]
print valid_filepath
>> /dirname/Spywaj.ttf (SO cannot display the chars in filename)
print type(valid_filepath)
>> <type 'str'>
print os.path.isfile(valid_filepath)
>> True
Run Code Online (Sandbox Code Playgroud)
在Latin-1(ISO-8859-1)和Windows-1252中,0xc2将是具有回音重音的大写字母A ......似乎不在您显示的代码中的任何位置!你能加点吗?
print repr(filename)
Run Code Online (Sandbox Code Playgroud)
在os.path.join调用之前(并且还将'/dirname'变量放入变量并打印其repr以获得完整性?).我想也许那个流浪的角色就在那里,但是你没有因某种原因看到它 - 它repr会揭示它.
如果您的文件名中包含Latin-1(或Win-1252)非Ascii字符,则必须使用Unicode - 和/或根据您的操作系统和文件系统,使用某些特定的编码.
编辑:OP确认,repr实际上有两个字节不可能是ASCII - 0xc2然后是0x88,对应于OP认为是一个小写的L.那么,该序列将是一个Unicode大写字母A在正常流行的UTF-8编码中的插入符号(代码点0x88)- 对于OP乞丐的解释,它看起来像小写字母L,但我想有些字体可能在图形上疯狂到足以引起这种混乱.
所以我首先尝试filename = filename.decode('utf-8')- 这应该允许os.path.join工作.如果open然后在生成的Unicode字符串(它可能工作,取决于文件系统和操作系统)下,下一次尝试是尝试使用该Unicode对象.encode('Latin-1')和.encode('utf-8').如果所有编码都不起作用,那么我认为OP尚未提供的操作系统和文件系统的信息变得至关重要.
我通过添加这些行/etc/apache2/envvars并重新启动Apache 来修复UnicodeDecodeError .
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
Run Code Online (Sandbox Code Playgroud)
如下所述:https: //docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/#if-you-get-a-unicodeencodeerror
我花了一些时间调试这个.