Python:是否可以为try块设置多个异常语句?

时间:2010-08-10 07:25:56

标签: python

try:
    case_no  = re.search("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
except:
       try:
           try:
               case_no  = re.search("Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
            except:
               case_no  = re.search("Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
        except:
              case_no  = "N/A"

正如您所看到的,上面的代码非常笨拙。我想知道我是否可以这样做。

try:
    XYZ
except:
    DOXYZ
except:
    DOXYZ

基本上我希望能够使用 - “如果异常则尝试X然后尝试Y,如果异常然后尝试Z”而不嵌套过多的状态。

7 个答案:

答案 0 :(得分:5)

可能你根本不应该检查例外情况?

patterns = [
  "Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",
  "Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",
  "Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<"   # same as #2?
]
text = br.response().read()
case_no  = "N/A"
for pattern in patterns:
  res = re.search(pattern, text)
  if res:
    case_no = res.group(1)
    break

答案 1 :(得分:3)

是的,只要你定义了异常条件......它就是可行的......

像:

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

但是,您必须定义异常类型。

答案 2 :(得分:3)

您正在寻找的行为的常见习语是:

try: foo()
except: pass

try: bar()
except: pass

但是你应该总是捕获一个特定的异常并确保它有意义。在你的情况下它根本没有意义 - 看看正则表达式是否匹配,测试None的结果:

r = br.response().read()
PATTERN1="..."
PATTERN2="..."
PATTERN3="..."
mo = re.search(PATTERN1, r) or re.search(PATTERN2, r) or re.search(PATTERN3, r)
case_no = mo.group(1) if mo else "N/A"

出于性能原因,您可以预编译正则表达式:

RE1 = re.compile("...")
RE2 = re.compile("...")
RE3 = re.compile("...")
mo = RE1.search(r) or RE2.search(r) or RE3.search(r)

此外,对于您的特定正则表达式模式,您可以轻松地将它们合并为一个,并使用命名组可以帮助提高可读性:

pat = r"""(Case|Citation) Number:</span></td><td><span class="Value">(?P<case_no>[^<]*?)<"""
mo = re.search(pat, r)
case_no = mo.group("case_no") if mo else "N/A"

最后,使用正则表达式解析HTML is the road to disaster,请考虑使用标准库中的HTMLParserBeautiful Soup

答案 3 :(得分:2)

不,不可能做你想做的事。多个except子句的语义包括捕获可能从相同代码块抛出的不同类型的异常。您必须嵌套语句或重新考虑代码才能获得所需的结果。

这种情况可能会更好地测试您期望导致异常的前提条件。

if test1():
    #dox
elif test2():
    #doy
elif test3():
    #doz

我还建议不要使用catchall except:短语,除非在您知道需要它们的非常特殊的情况下。

答案 4 :(得分:0)

如果您在每个try / except块中执行相同或类似的操作,则可以使用循环

case_no = "N/A"
for _ in range(3):
    try:
        case_no  = re.search("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
        break
    except SomeExplicitlyCaughtExceptions:
        pass

当然,这种形式没有任何意义,因为尝试三次同样的事情会产生相同的结果。

答案 5 :(得分:0)

你最好重组你的代码:

success = False

for _ in xrange(MAX_ATTEMPTS):
    try:
        XYZ
        success = True
        break
    except:
        pass

if not success:
   DOXYZ

但最好明确指定异常。你真的想抓住KeyboardInterrupt吗?

答案 6 :(得分:0)

如果我这样做,我会避免例外情况:

count = 3
caseRe = re.compile("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<")
while count > 0:
   text = br.response().read()
   mo = caseRe.search(text)
   if mo is None:
       count -= 1
       continue
   case_no  = mo.group(1)
   break

if count == 0:
    case_no = "N/A"