忽略来自生成器的异常

coa*_*nor 3 python for-loop exception generator

通过使用os.walk()像这样遍历文件夹:

for subdir, dirs, files in os.walk(path):
    do something...
Run Code Online (Sandbox Code Playgroud)

会抛出异常:UnicodeDecodeError,我想忽略异常并继续,我试过这个:

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

正如评论所说, continue异常部分是语法错误。有没有办法忽略异常继续遍历?

异常是从 抛出的os.walk(),所以放在try/except里面for是无法捕捉到异常的。该os.walk()会返回一个蟒蛇发电机,如何捕捉其中的例外呢?

小智 5

更新:

我最初认为错误是由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...
Run Code Online (Sandbox Code Playgroud)

基本上,这是利用os.walk返回生成器对象的事实。这允许我们调用next它,从而控制每一步的迭代。

subdir, dirs, files = next(walker)线尝试推进迭代。如果 aUnicodeDecodeError被提出,它会被记录下来,我们继续下一步。如果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
Run Code Online (Sandbox Code Playgroud)

另外,做:

except Exception, e:
Run Code Online (Sandbox Code Playgroud)

已被弃用。您应该使用as关键字代替,

except Exception as e:
Run Code Online (Sandbox Code Playgroud)

当你在做的时候,你应该用Exception特定的替换泛型UnicodeDecodeError

except UnicodeDecodeError as e:
Run Code Online (Sandbox Code Playgroud)

您应该始终尝试捕获最具体的异常。否则,您可能会意外捕获到您不打算处理的异常。