Python尝试/除了:尝试多个选项

时间:2014-07-08 11:33:34

标签: python exception-handling

我试图从网页上抓取一些信息,这些信息与信息的位置不一致。我有代码来处理各种可能性;我想要的是按顺序尝试它们,如果它们都不起作用我想要优雅地失败并继续前进。

也就是说,在伪代码中:

try:
    info = look_in_first_place()
otherwise try:
    info = look in_second_place()
otherwise try:
    info = look_in_third_place()
except AttributeError:
    info = "Info not found"

我可以使用嵌套的try语句执行此操作,但如果我需要尝试15种可能性,那么我需要15级缩进!

这似乎是一个微不足道的问题,我觉得我错过了一些东西,但是我已经把它搜到了地上,找不到任何看起来与这种情况相同的东西。是否有合理的Pythonic方式来做到这一点?

编辑:正如约翰的(相当不错的)解决方案提出的那样,为简洁起见,我将上面的每个查询都写成一个函数调用,而实际上它通常是BeautifulSoup的一小块。 soup.find('h1', class_='parselikeHeader')等来电。当然我可以将它们包装在函数中,但是这些简单的块看起来有点不雅 - 如果我的速记改变了问题就道歉了。

这可能是一个更有用的插图:

try:
    info = soup.find('h1', class_='parselikeHeader').get('href')
if that fails try:
    marker = soup.find('span', class_='header')
    info = '_'.join(marker.stripped_strings)
if that fails try:
    (other options)
except AttributeError:
    info = "Info not found"

1 个答案:

答案 0 :(得分:8)

如果每个查找都是一个单独的函数,您可以将所有函数存储在一个列表中,然后逐个迭代它们。

lookups = [
    look_in_first_place,
    look_in_second_place,
    look_in_third_place
]

info = None

for lookup in lookups:
    try:
        info = lookup()
        # exit the loop on success
        break    
    except AttributeError:
        # repeat the loop on failure
        continue

# when the loop is finished, check if we found a result or not
if info:
    # success
else:
    # failure