KorP
@KorP
Кратко о себе

Оцените кусочек кода

Простите, что обращаюсь с такой просьбой, но я ещё не отыскал более-менее живые русскоязычные ресурсы по питону. Я только взялся за его изучение и тут как раз мне на глаза попалась статья virtustilus — Приводим русские тексты на Mac OS X в одну кодировку Python-скриптом. Мне показался код слишком накрученным и я попытался переписать его на свой лад. И хотелось бы услышать об ошибках, мною совершённых. Код простенький и небольшой:
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import chardet

def converter(path, file):
	if file.endswith(".txt"):
		P = os.path.join(path, file)
		with open(P, "r") as F:
			text = F.read()
			enc = chardet.detect(text).get("encoding")
			if enc and enc.lower() != u"utf-8":
				try:
					text = text.decode(enc)
					text = text.encode("utf-8")
					with open(P, "w") as f:
						f.write(text)
						print P+u" сконвертирован."
				except:
					print "Ошибка в имени файла: название содержит русские символы или пробелы."
				print u"-------------------------------"
				
path = raw_input(u"Input path or file:")
if os.path.isdir(path) == True:
	for (path, dirs, files) in os.walk(path):
		for file in files:
			converter(path, file)
elif os.path.isfile(path) == True:
	converter(os.path.dirname(path), os.path.basename(path))
				
sys.exit(0)

Попутно у меня есть несколько вопросов:
1. Что делать если файл содержит русские буквы или пробелы? Пока они просто подпадают под исключение и ничего с ними не делается, но может быть есть способы? Гуглинг не сильно помог в ответе на этот вопрос&
2. Как правильно в raw_input вставить русские символы в строку «приветствия»? Пока он ругается
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

3. Как при помощи .endswith() указать несколько расширений файлов?

Заранее благодарен за помощь. Если вопросы совсем уж детские — вы меня простите, ещё не очень освоился с питоновской документацией, я с ним от силы всего пару недель знаком. :-[
  • Вопрос задан
  • 4243 просмотра
Пригласить эксперта
Ответы на вопрос 2
0. Укажите версию питона.

1. Узнайте что за исключение кидается except Exception as exception и идите в этом направлении, но у меня просто не находит файл по вводимой строке и пропуская os.path.isdir и os.path.isfile выходит (у вас нет проверки что можно ввести неверное имя файла).
2. Странно, у меня на венде работает, так что не подскажу.
3. Нужно пробежаться по всем расширениям и проверить каждое, например если перечислять расширения через запятую.
any([file_path.endswith(extension) for extension in '.rar,.txt'.split(',')])

4. Почитайте pep8, давайте переменным осмысленные имена, используйте u"%s сконвертирован." % file_path вместо file_path + u" сконвертирован.".
5. Используйте if __name__ == '__main__':
6. В функцию converter лучше сразу передавать file_path
7. Возможно Вам не нужно использовать raw_input, а передавать параметры в виде аргументов (тут поможет sys.argv или argparser)
8. Вместо print u"-------------------------------" можно писать print u"-" * 20
9. Лучше добавлять атрибут 'b' в команду open: open(file_path, 'rb') и open(file_path, 'wb')
Ответ написан
AterCattus
@AterCattus
Люблю быстрый backend
Комментарии к ответу tbicr:
>>0. Укажите версию питона.
Если речь и разделении Python2/3, то разве этот код вообще сможет запуститься на Python3? Там же в принципе нельзя указать u-префикс строкам, т.к. он идет по умолчанию.

>>1. Узнайте что за исключение кидается except Exception as exception
Исключения при перекодировке строк — общий родитель для них в данном случае UnicodeError.

Комментарии к ТС:

1) Вы пишите u«utf-8», но при этом «Ошибка в имени файла...» без u-префикса. Лучше наоборот :)

2) Чем меньше вложенность — тем лучше (в разумных пределах). Вместо
    if file.endswith(".txt"):
        P = os.path.join(path, file)
        ...

лучше написать:
    if not file.endswith(".txt"):
        continue
    P = os.path.join(path, file)
    ...

Плоское лучше, чем вложенное.
Flat is better than nested.

3) if os.path.isdir(path) == True:
не надо так. просто
if os.path.isdir(path):

4) вместо
    for (path, dirs, files) in os.walk(path):
        for file in files:
            converter(path, file)

можно использовать glob.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы