Python os.stat和unicode文件名

int*_*tar 16 python unicode operating-system

在我的Django应用程序中,用户上传了名称中带有unicode字符的文件.

当我下载文件时,我正在打电话:

os.path.exists(media)
Run Code Online (Sandbox Code Playgroud)

测试文件是否存在.反过来,这似乎在呼唤

st = os.stat(path)
Run Code Online (Sandbox Code Playgroud)

然后会出现错误:

UnicodeEncodeError:'ascii'编解码器无法对位置92中的字符u'\ xcf'进行编码:序数不在范围内(128)

我该怎么办?是否有path.exists选项来处理它?

更新:实际上,我所要做的就是将参数编码为exists,即.

os.path.exists(media.encode('utf-8')
Run Code Online (Sandbox Code Playgroud)

谢谢所有回答的人.

Gle*_*ard 8

我假设你在Unix中.如果没有,请记得说出你所在的操作系统.

确保您的语言环境设置为UTF-8.默认情况下,所有现代Linux系统都会这样做,通常是将环境变量LANG设置为"en_US.UTF-8"或其他语言.另外,请确保您的文件名以UTF-8编码.

使用该集合,即使在Python 2.x中,也无需使用任何语言来编码访问文件.

[~/test] echo $LANG
en_US.UTF-8
[~/test] echo testing > ??
[~/test] python2.6
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.stat("??")
posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230)
>>> os.stat(u"??")
posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230)
>>> open("??").read()
'testing\n'
>>> open(u"??").read()
'testing\n'
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请运行"locale"; 如果值为"C"而不是en_US.UTF-8,则可能没有正确安装区域设置.

如果你在Windows中,我认为Unicode文件名应该始终正常工作(至少对于os/posix模块),因为Windows中的Unicode文件API是透明支持的.

  • 我在控制台中尝试使用相同的字母ß,它可以工作,但是当我在脚本中执行它时它没有,我得到IOError,没有这样的文件或目录,并且该字符已被编码为'\ xc3\x9f " (3认同)

Del*_*eet 6

这些解决方案都不适合我。但是,我确实找到了(a?)解决方案。如果使用 WSGI,Apache 设置中还有另一个地方必须添加语言环境设置。官方文档在这里。将以下两行添加到/etc/apache2/envvars(在 Ubuntu 上):

export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
Run Code Online (Sandbox Code Playgroud)

然后重启服务器。这解决了我的问题。


Ign*_*ams 1

在调用之前编码为文件系统编码。请参阅locale模块。

  • 您必须使用本机系统的编码来引用文件。尝试“locale.nl_langinfo(locale.CODESET)”。 (2认同)