Найти - Пользователи
Полная версия: Настройка интерпретатора, в частности кодировка
Начало » Python для новичков » Настройка интерпретатора, в частности кодировка
1 2
x_faf-pythoner_x
Доброго времени суток.

Изучаю python, и в качестве оболочки использую ipython.

Интересует вопрос, как настроить в python sys.getdefaultencoding() ?

В скриптах использу это:
-*- coding: utf8 -*-
Надо чтоб вместо ‘ascii’ стоял ‘utf8’.
:wq
diam123
sys.setdefaultencoding()
x_faf-pythoner_x
Если бы…
#!/usr/bin/env python
# -*-coding: utf8 -*-
import sys,os
sys.setdefaultencoding('utf8')
AttributeError: 'module' object has no attribute 'setdefaultencoding'
python –version
Python 2.7.1+
python3 –version
Python 3.2
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=ru_RU:en
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
diam123
C:\Documents and Settings\username>python -S
Python 2.6 (r26:66721, Oct 2 2008, 11:35:03) [MSC v.1500 32 bit (Intel)] on win
32
>>> import sys
>>> sys.setdefaultencoding()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: setdefaultencoding() takes exactly 1 argument (0 given)
>>> sys.setdefaultencoding(u"UTF-8")
>>>
Обратите внимание на python -S
И собственно, непосредственный вопрос - зачем это ?
x_faf-pythoner_x
Да как бы сказать-то?

Использую инструменты Python для архивации документов.

Имена исходных файлов на русском. После обработки имена в архивах становятся кракозябами.

Написавши, кажись, понял.
Чтобы бардака такого не было, нужно в скрипте указать -*- coding: ascii -*- или нет?
diam123
А явное encode/decode для строк делали?
Подозреваю, что проблема не там (в смысле не там, где вы ищете)…
Если можно, код покажите :)
P.S. Если это zipfile, то вам наверное стоит глянуть сюда:
http://python.su/forum/viewtopic.php?id=1614
x_faf-pythoner_x
Исходные:
/backup/users/Науменко\ Аня/
/backup/users/Науменко Аня/Нетта/Диета, не ешь не то не это.doc

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import os,tarfile,time,gzip,stat,sys

# vars
files_list = list()

def pack(_dest, _source):
pack_name = _dest + "" + str(time.strftime("%d.%m.%Y", time.localtime())) + ".tar.bz2"
_pack = tarfile.open(pack_name, 'w|bz2')
for name in _source:
_pack.add(name)
_pack.close()

def get_info(file_name):
time_format = "%d-%m-%Y"
file_stat = os.stat(file_name)
mod_time = time.strftime(time_format, time.localtime(file_stat[stat.ST_MTIME]))
access_time = time.strftime(time_format, time.localtime(file_stat[stat.ST_ATIME]))
return file_name, mod_time, access_time

def check_extention(file_name):
_stat = get_info(file_name)
try:
extention = _stat[0].split(".")[1]
if _stat[0].split(".")[1] in ('doc', 'docx', 'xls', 'xlsx'):
return 1
else:
return 0
except IndexError as err:
print(err)

def get_dirs(_path = "/backup/users/"):
dirs_list = list()
input_path = os.listdir(_path)
try:
for cur_dir in input_path:
dirs_list.append(cur_dir + "/")
except OSError as err:
print err
return dirs_list

def prnt(_list):
for name in _list:
print name

def main():
try:
for root,dirs,files in os.walk("/backup/users/Науменко Аня"):
for name in files:
if (check_extention(os.path.join(root,name))):
#tmp = str(os.path.join(root,name)).encode("utf8")
tmp = os.path.join(root,name)
files_list.append(os.path.join(tmp))

except OSError as err:
print err
pack("/backup/arch/", files_list)
main()
#prnt(files_list)
Результат:
/backup/users/&#208;&#157;&#208;°&#209;&#402;&#208;&#188;&#208;µ&#208;&#189;&#208;&#186;&#208;&#190; &#208;&#144;&#208;&#189;&#209;&#143;/&#208;&#157;&#208;µ&#209;‚&#209;‚&#208;°/
/backup/users/&#208;\302\235&#208;°&#209;\302\203&#208;&#188;&#208;µ&#208;&#189;&#208;&#186;&#208;&#190; &#208;\302\220&#208;&#189;&#209;\302\217/&#208;\302\235&#208;µ&#209;\302\202&#209;\302\202&#208;°/&#208;\302\224&#208;&#184;&#208;µ&#209;\302\202&#208;°, &#208;&#189;&#208;µ &#208;µ&#209;\302\210&#209;\302\214 &#208;&#189;&#208;µ &#209;\302\202&#208;&#190; &#208;&#189;&#208;µ &#209;\302\215&#209;\302\202&#208;&#190;.doc

In [15]: sys.getdefaultencoding()
Out[15]: 'ascii'
Если же делать через закомментированную строку, то результат:
UnicodeDecodeError: ‘ascii’ codec can't decode byte 0xd0 in position 14: ordinal not in range(128)

Вот она эта проблема :(
py.user.next
x_faf-pythoner_x
for root,dirs,files in os.walk("/backup/users/Науменко Аня"):
во втором питоне нужно ставить u'абвг', потом применять .encode('нужная_кодировка')

>>> s = u'абвг'
>>> print s
абвг
>>> s.encode('utf-8')
'\xd0\xb0\xd0\xb1\xd0\xb2\xd0\xb3'
>>>
перед упаковкой нужно вывести путь на экран

x_faf-pythoner_x
# -*- coding: utf-8 -*-
относится к самому исходному файлу, чтобы правильно декодировать то, что в нём написано
эта кодировка должна совпадать с кодировкой исходного файла
например, с кодировкой # -*- coding: ascii -*- интерпретатор не сможет раскодировать “/backup/users/Науменко Аня”, так как там кириллица, которой в ascii нет

принимая символы снаружи, раскодируешь их в юникод
работаешь с юникодовыми строками
записывая символы наружу, кодируешь символы из юникода в нужную кодировку
diam123
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import os,tarfile,time,gzip,stat,sys

# vars
files_list = []

def pack(_dest, _source):
pack_name = "{0}{1}.tar.bz2".format(_dest, str(time.strftime("%d.%m.%Y", time.localtime())))
packed = tarfile.open(pack_name, 'w|bz2', format=tarfile.PAX_FORMAT)
for name in _source:
packed.add(name)
packed.close()

def get_info(file_name):
time_format = "%d-%m-%Y"
file_stat = os.stat(file_name)
mod_time = time.strftime(time_format, time.localtime(file_stat[stat.ST_MTIME]))
access_time = time.strftime(time_format, time.localtime(file_stat[stat.ST_ATIME]))
return file_name, mod_time, access_time

def check_extention(file_name):
need_extensions = ('.doc', '.docx', '.xls', '.xlsx')
root, file_extension = os.path.splitext(file_name)

return file_extension in need_extensions

def get_dirs(_path = "/backup/users/"):
dirs_list = []
try:
full_list = os.listdir(_path)
for cur_dir in full_list:
if os.path.isdir(cur_dir):
dirs_list.append(cur_dir)
except OSError as err:
print err
return dirs_list

def prnt(_list):
for name in _list:
print name

def main():
try:
for root, dirs, files in os.walk(u"D:\TEST\BACKUP\Науменко Аня"):
for name in files:
if check_extention(os.path.join(root,name)):
tmp = os.path.join(root,name)
files_list.append(os.path.join(tmp))

except OSError as err:
print err
pack(u"D:\TEST\BACKUP", files_list)
main()
#prnt(files_list)
Обратите внимание, в строке “for root, dirs, files in os.walk(u”D:\TEST\BACKUP\Науменко Аня“):”
НЕ НУЖНО делать перекодировку. Точно НУЖНО давать путь для функции os.walk в виде юникод-строки (u“/home/Аня Науменко”, а не “/home/Аня Науменко”). Кроме косметических изменений единственное изменение - в строке “packed = tarfile.open(pack_name, ‘w|bz2’, format=tarfile.PAX_FORMAT)”. Согласно официальной документации модуля tarfile, при создании обьекта типа TarFile формат используемого архива по умолчанию format=DEFAULT_FORMAT, где
tarfile.DEFAULT_FORMAT
The default format for creating archives. This is currently GNU_FORMAT.
Согласно этому абзацу из той же документации (пункт 12.5.5. Unicode issues):
The default value for encoding is the local character encoding. It is deduced from sys.getfilesystemencoding() and sys.getdefaultencoding(). In read mode, encoding is used exclusively to convert unicode names from a pax archive to strings in the local character encoding. In write mode, the use of encoding depends on the chosen archive format. In case of PAX_FORMAT, input names that contain non-ASCII characters need to be decoded before being stored as UTF-8 strings. The other formats do not make use of encoding unless unicode objects are used as input names. These are converted to 8-bit character strings before they are added to the archive.
Я пришёл к выводу изменить формат на PAX.
P.S. относительно функции os.walk(). Всё просто, даёте на вход путь в виде юникод-строки, на выходе получаете юникод-строку.Не заморачиваетесь с перекодированием, “оно само”. По этой же причине при создании архива вы не заморачиваетесь с перекодированием.

Короч, архив создан в бубунтах - открывается в форточках без проблем с кодировками. Архив создан в форточках - открывается в бубунтах без проблем с крдировками. Архиваторы - IZArc и гномовский дефолтный.
x_faf-pythoner_x
Спасибо огромное, работает !
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB