Python os.stat и имена файлов в юникоде - PullRequest
16 голосов
/ 16 января 2010

В моем приложении Django пользователь загрузил файл с символом Unicode в имени.

Когда я загружаю файлы, я звоню:

os.path.exists(media)

чтобы проверить, что файл там. Это, в свою очередь, кажется, называется

st = os.stat(path)

Который затем взрывается с ошибкой:

UnicodeEncodeError: кодек 'ascii' не может кодировать символ u '\ xcf' в позиции 92: порядковый номер не в диапазоне (128)

Что я могу с этим сделать? Существует ли опция path.exists для ее обработки?

Обновление: на самом деле все, что мне нужно было сделать, это закодировать аргумент для существования, т. Е.

os.path.exists(media.encode('utf-8')

Спасибо всем, кто ответил.

Ответы [ 5 ]

8 голосов
/ 16 января 2010

Я предполагаю, что вы в 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'

Если это не работает, запустите «locale»; если вместо en_US.UTF-8 указаны значения «C», возможно, языковой стандарт установлен неправильно.

Если вы находитесь в Windows, я думаю, что имена файлов Unicode всегда должны работать (по крайней мере, для модулей os / posix), поскольку API файлов Unicode в Windows поддерживается прозрачно.

4 голосов
/ 18 сентября 2016

Ни одно из этих решений не помогло мне. Тем не менее, я нашел (а?) Решение. В настройках Apache есть еще одно место, где нужно добавить настройку локали, если используется WSGI. Официальные документы здесь . Добавьте следующие две строки в /etc/apache2/envvars (в Ubuntu):

export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

Затем перезапустите сервер. Это решило мою проблему.

2 голосов
/ 16 января 2010

Кодирование в кодировку файловой системы перед вызовом. См. Модуль locale.

1 голос
/ 29 марта 2017

Такую ошибку легко получить при запуске службы (например, gunicorn) из Upstart.

Чтобы это исправить, установите env в файле upstart:

env LANG=en_US.UTF-8
env LC_CTYPE=en_US.UTF-8
env LC_ALL=en_US.UTF-8
1 голос
/ 28 августа 2015

Измените ваш http-сервер на использование языка UTF-8. Например, я использую apache2 на CentOS. Я изменил / etc / sysconfig / httpd настройки локали по HTTPD_LANG:

# CentOS use /etc/sysconfig/httpd to config environment variables.
#
# By default, the httpd process is started in the C locale; to
# change the locale in which the server runs, the HTTPD_LANG
# variable can be set.
#
# HTTPD_LANG=C
HTTPD_LANG=en_US.UTF-8  # you can change to your locale.
...