Python:一个try块可以有多个异常语句吗?

0 投票
7 回答
3346 浏览
提问于 2025-04-16 02:34
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 个回答

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

不过,你必须定义异常的类型。

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 是个大坑,建议使用标准库中的 HTMLParser 或者 Beautiful Soup

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

撰写回答