LINUX.ORG.RU

Вместо <> :) почему после перехвата должен цикл прерываться?

Но почему-то кажется, что ты хочешь чего-то другого, но этого не написал.

Shtsh ★★★★
()
Последнее исправление: Shtsh (всего исправлений: 1)

try...except?

anonymous
()
Ответ на: комментарий от Esper

Исключение — не в теле цикла

В самом for .. in

olegkrutov ★★
() автор топика
Ответ на: комментарий от beresk_let

Похоже, я не сделал акцент на том, где именно исключение

А оно в самом for. Конкретно у меня — ошибка декодировки UnicodeDecodeError.

olegkrutov ★★
() автор топика
Последнее исправление: olegkrutov (всего исправлений: 1)

Внутри функции log отлавливай.
Только надо не open as log тогда использовать, а свой итератор написать.

Хотя вообще похоже что у тебя где-то глубже проблема.

Goury ★★★★★
()
Последнее исправление: Goury (всего исправлений: 1)
Ответ на: комментарий от Goury

Так функция-то — обычное открытие файла.

А проблема не глубже кривизны входных данных, на которых валится питоновский декодировщик внутри этого самого итератора in (кстати, на кой он вообще в третьем питоне эти строки куда-то декодирует, если они гордо заявляли, что у них куда ни плюнь, везде юникод)?

olegkrutov ★★
() автор топика

сделать обертку-итератор над результатом open и в ней перехватывать

anonymous
()
Ответ на: Так функция-то — обычное открытие файла. от olegkrutov

(кстати, на кой он вообще в третьем питоне эти строки куда-то декодирует, если они гордо заявляли, что у них куда ни плюнь, везде юникод)?

У них то, может, и юникод, а в поданном на вход файле - может, и нет.

anonymous
()

Передай функции open правильный параметр encoding.

Ну, либо проверяй свой входной файл на соответствие тому, что ожидает пайтон от utf-8.

HerrWeigel ★★★★
()
Последнее исправление: HerrWeigel (всего исправлений: 1)
Ответ на: комментарий от Goury

Ну например:

Traceback (most recent call last): File «/home/user/filelist2domain.py», line 24, in <module> for line in log: File «/usr/lib/python3.5/codecs.py», line 321, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd1 in position 6903: invalid continuation byte

olegkrutov ★★
() автор топика
Ответ на: комментарий от HerrWeigel

Ээээ... я не могу его проверить, не я его создаю. Мне нужно при ошибке просто продолжить дальше.

Кодировка верная, ошибка — на втором десятке тыщ записей.

olegkrutov ★★
() автор топика
Ответ на: комментарий от beresk_let

В процессе, да, это понятно

Точнее — в процессе перекодировки строки из него

olegkrutov ★★
() автор топика
Ответ на: Исключение — в самом for от olegkrutov

Тогда только ручками итерировать:

with open('servo', mode="r", encoding="utf-8") as log:
     lines = iter(log)
     while True:
         try:
             line = next(lines)
             < . . . >
         except StopIteration:
             break
         except:
             pass 

Esper
()
Последнее исправление: Esper (всего исправлений: 1)
Ответ на: комментарий от Esper

О, спасибо!

Счас попробую. Но как-то это резко отличается от мантр про pythonic way ;)))

olegkrutov ★★
() автор топика
Ответ на: комментарий от Goury

Да спасибо, вариант со своим итерированием решил проблему

.

olegkrutov ★★
() автор топика
Ответ на: комментарий от Esper

Это как-то слишком костыльно. IMHO, более правильно будет читать из файла байты и переделывать их в строки руками (если это вообще нужно в этой задаче):

with open('servo', mode="rb") as log:
    for byte_line in log:
        try:
            text_line = byte_line.decode('utf-8')
        except UnicodeDecodeError:
            continue
        <...>
anonymous_coward
()
Ответ на: комментарий от anonymous_coward

Ну, мне переделывать ничего и не надо было,

Но в принципе что так, что этак — а вот кстати, разве в режиме «b» чтение строк работает? Зы: я немного удивлен, что нет какого-либо модификатора для подобных случаев типа for .. in .. handler()

olegkrutov ★★
() автор топика
Последнее исправление: olegkrutov (всего исправлений: 1)
Ответ на: Ну, мне переделывать ничего и не надо было, от olegkrutov

а вот кстати, разве в режиме «b» чтение строк работает?

В режиме 'b' open возвращает байты, а не строки. А если речь про итерацию по строкам файла, то да, с чего бы ей не работать?

Зы: я немного удивлен, что нет какого-либо модификатора для подобных случаев типа for .. in .. handler()

Нет его потому, что в таких ситуациях надо исходную проблему решать, а не костыли городить. Здесь, например, проблема, судя по всему, в том, что неюникодный файл пытаются читать так, словно внутри юникод. Вот её и нужно решать.

anonymous_coward
()
Ответ на: комментарий от anonymous_coward

Так вопрос и есть, как грамотно средствами питона подстраховаться

Потому что файл, к примеру, совершенно точно юникодный, но данные в нём иногда бывают «битые», и с этим ничего не сделать, надо как-то обрабатывать ситуацию.

olegkrutov ★★
() автор топика
Ответ на: комментарий от anonymous_coward

надо исходную проблему решать
неюникодный файл пытаются читать так, словно внутри юникод

С неюникодом юникода проблем не бывает.

Читаешь бинарно utf-8? Значит так:

Прочитал байт (учар), если он < 128, значит это однобайтный символ, иначе если он < 224, читай еще один байт, иначе если он < 240, читай еще два, иначе если он < 248, читай еще три, иначе если он < 252, читай еще четыре, иначе читай еще пять. Символ максимум шестибайтный.

Проблема битости символов может быть только из-за BOM в начале файла (но в утф-8 он НЕ ВЛИЯЕТ НА ПОРЯДОК БАЙТ) и в конце если там байты символа не все (на основе первого «опорного» байта).

Даже если в таблице место не занято — тебе покажут фалбечные вопросики в ромбике и ничего не упадет.

Что там нагородили питоностроители или ТС — я хз. В питон не умею.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deadNightTiger

В идеальном мире, конечно, круто жить

Но подобный подход, как мне кажется, строго равен «ах у меня переполнение буфера? Это не моя прога глючит, сами виноваты — зачем пихаете на вход более N байт!»

olegkrutov ★★
() автор топика
Ответ на: комментарий от deep-purple

Получается, что надо писать сразу на С

Потому что вся хваленая питонская гибкость и удобство идут лесом при малейшем чихе.

olegkrutov ★★
() автор топика

Может я чего не догоняю, может лог надо в UTF сразу писать?

import array
with open('servo', mode="rb") as log:
    for byte_line in log:
        try:
            text_line = byte_line.decode('utf-8')
        except UnicodeDecodeError:
            print list(bytearray(byte_line))
            continue
Как то так.

X286
()
Ответ на: комментарий от X286

Лог пишет другая софтина

В которую влезть немного проблематично. Поэтому нужно обрабатывать возможные косяки уже после получения.

olegkrutov ★★
() автор топика
Ответ на: комментарий от Virtuos86

Что есть ОП?

И собственно вопрос был как раз, как правильно её решить именно на питоне. В результате имеем пару дельных советов про написание своего итератора, которые помогли решить задачу, и подавляющую массу советов про «нам нужны входные данные без дефектов» :)

olegkrutov ★★
() автор топика

Так битые данные и нужно обрабатывать, а не собственные итераторы без нужны городить. Я же привёл код, который именно так и работает.

anonymous_coward
()
Ответ на: комментарий от anonymous_coward

Да, ваш вариант логичней, хотя и с итератором работает тоже

Спасибо!

olegkrutov ★★
() автор топика
Ответ на: комментарий от anonymous_coward
with open('servo', mode="rb") as log:
    for byte_line in log:
        try:
            text_line = byte_line.decode('utf-8')
        except UnicodeDecodeError:
            continue
        <...>

Правильно, так его, это глупое исключение! Его же зря определили, подавляй, подавляй его, пусть юзер считает, что у него все хорошо.

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

О, мсье не проходил в школе слово "пример"?

Мсье наверняка любопытно будет узнать, что «пример» — это просто один из вариантов того, как можно сделать, а на основе «примера» можно сделать что-то своё, к примеру, обработку этого самого исключения...

olegkrutov ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.