2014-12-23 2 views
3

С помощью os.walk() пройти папку так:Игнорировать исключение из генератора

for subdir, dirs, files in os.walk(path): 
    do something... 

Там будет бросать исключение: UnicodeDecodeError, я хочу, чтобы игнорировать исключение и продолжать, и я попытался это:

try: 
    for subdir, dirs, files in os.walk(path): 
     do something... 
except Exception, e: 
    logging.exception(e) 
    continue # this continue is illegal 

, как отмечается в комментарии, continue в части исключения является синтаксической ошибкой. Есть ли способ игнорировать исключение и продолжать движение?

Исключение составляет от os.walk(), поэтому положить try/except в пределах for не может поймать исключение. os.walk() вернет генератор питона , Как поймать исключение в нем?

ответ

4

Update:

Первоначально я думал, что ошибка была воспитываются в do something... кода. Так как на самом деле воспитываются os.walk, вам нужно будет сделать что-то немного по-другому:

walker = os.walk(path) 
while True: 
    try: 
     subdir, dirs, files = next(walker) 
    except UnicodeDecodeError as e: 
     logging.exception(e) 
     continue 
    except StopIteration: 
     break 

    do something... 

В основном, это, воспользовавшись тем, что os.walk возвращающего generator object. Это позволяет нам называть next и тем самым контролировать итерацию на каждом шаге.

Линия subdir, dirs, files = next(walker) пытается продвигать итерацию. Если поднят UnicodeDecodeError, он регистрируется и мы переходим к следующему шагу. Если возникает исключение StopIteration, это означает, что мы закончили движение по дереву каталогов. Итак, мы разбиваем цикл.


Поскольку continue потребности быть внутри цикла, вам нужно будет переместить try/except блок там, а также:

for subdir, dirs, files in os.walk(path): 
    try: 
     do something... 
    except Exception, e: 
     logging.exception(e) 
     continue # this continue is *not* illegal 

Кроме того, выполнив:

except Exception, e: 

устарела , Вы должны использовать ключевое слово as вместо ,:

except Exception as e: 

Пока вы на него, вы должны заменить общий Exception с конкретным UnicodeDecodeError:

except UnicodeDecodeError as e: 

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

+0

Также лучше поймать конкретный UnicodeDecodeError, а не любое общее исключение «сделать что-то». – xnx

+0

Исключение исключение из 'os.walk()', а не в цикле 'for', поэтому try/except ничего не делать с этим исключением. – coanor

+0

@coanor - Смотрите мое редактирование. – iCodez

-1
for subdir, dirs, files in os.walk(path): 
    try: 
     do something... 
    except Exception, e: 
     logging.exception(e) 
     continue # this continue is illegal 
+0

Это ничего не отвечает, оно копирует только часть кода из исходного вопроса. –

0

Да, вы могли бы попытаться поймать исключение под цикл с чем-то вроде этого:

import os 

path = '.' 

for subdir, dirs, files in os.walk(path): 
    try: 
     print(subdir, dirs, files) 
    except UnicodeDecodeError: 
     continue 
    except Exception: 
     print('Fatal error') 
0

У меня была похожая ситуация в то время как итерация по ссылкам с помощью Beautiful Soup.Это код, который я написал для этого:

class suppressed_iterator: 
    def __init__(self, wrapped_iter, skipped_exc = Exception): 
     self.wrapped_iter = wrapped_iter 
     self.skipped_exc = skipped_exc 

    def __next__(self): 
     while True: 
      try: 
       return next(self.wrapped_iter) 
      except StopIteration: 
       raise 
      except self.skipped_exc: 
       pass 

class suppressed_generator: 
    def __init__(self, wrapped_obj, skipped_exc = Exception): 
     self.wrapped_obj = wrapped_obj 
     self.skipped_exc = skipped_exc 

    def __iter__(self): 
     return suppressed_iterator(iter(self.wrapped_obj), self.skipped_exc) 

Пример:

class IHateThirteen: 
    ''' Throws exception while iterating on value 13 ''' 

    def __init__(self, iterable): 
     self.it = iter(iterable) 

    def __iter__(self): 
     return self 

    def __next__(self): 
     v = next(self.it) 
     if v == 13: 
      raise ValueError('I hate 13!') 
     return v 

# Outputs [10, 11, 12, 14, 15] 
exception_at_thirteen = IHateThirteen([10, 11, 12, 13, 14, 15]) 
print(list(suppressed_generator(exception_at_thirteen))) 

# Raises ValueError 
exception_at_thirteen = IHateThirteen([10, 11, 12, 13, 14, 15]) 
print(list(exception_at_thirteen)) 

Вы можете исправить свой код, используя выше код:

for subdir, dirs, files in suppressed_generator(os.walk(path)): 
    do something... 

Приведенный выше код может быть продлен еще на имеют обратные вызовы для пропущенных типов исключений, если это необходимо, но в таком случае может быть более pythonic использовать iCodez's answer.

Смежные вопросы