2014-12-23 82 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/exceptfor內不能捕捉到異常。 os.walk()將返回一個python生成器,如何捕捉它內的異常?

回答

4

更新:

我原本以爲這是由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: 

當你在這,你應該與特定UnicodeDecodeError取代通用Exception

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

是的,你可以嘗試捕獲異常下的for循環像這樣的東西:

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

我也有類似的情況在遍歷使用美麗的湯鏈接。這個是我寫的代碼:

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... 

上面的代碼可以擴展更多如果需要,每個跳過的異常類型都有回調函數,但在這種情況下使用iCodez's answer可能會更麻煩。