简体   繁体   English

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

[英]Python: Is it possible to have multiple exceptions statments for a try block?

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"

As you can see the above code is quite clumsy. 如您所见,上面的代码非常笨拙。 I want to know if there is any way I can do like this. 我想知道是否有什么办法可以做到这一点。

try:
    XYZ
except:
    DOXYZ
except:
    DOXYZ

Basically I want to be able to use - "try X if exception then try Y if exception then try Z" without nesting too much statemtns. 基本上,我希望能够使用-“在异常情况下尝试X,然后在异常情况下尝试Y,然后再尝试Z”而不嵌套太多statemtns。

Probably you shouldn't be checking exception at all? 也许您根本不应该检查异常?

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

Yes, it is posible, as long as you define exception condition... 是的,只要您定义异常条件,它都是可能的。

Like: 喜欢:

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

But, you must define the exception type. 但是,您必须定义异常类型。

A common idiom for the behavior you're looking for is something like: 您要寻找的行为的常见用法是:

try: foo()
except: pass

try: bar()
except: pass

But you should always catch a specific exception and make sure it makes sense. 但是您应该始终捕获特定的异常,并确保它是合理的。 In your case it simply doesn't make sense - to see if the regular expression matched, test the result for None : 在您的情况下,这根本没有意义-要查看正则表达式是否匹配,请测试结果是否为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"

For performance reasons you can precompile your regexes: 出于性能原因,您可以预编译正则表达式:

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

Also, for your specific regex patterns you can easily combine them into one, and using a named group can help readability: 另外,对于您的特定正则表达式模式,您可以轻松地将它们组合为一个,使用命名组可以提高可读性:

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"

And finally, using regular expressions to parse HTML is the road to disaster , consider using HTMLParser from the standard lib or Beautiful Soup . 最后,使用正则表达式解析HTML 是通往灾难的道路 ,请考虑使用标准lib或Beautiful Soup中的 HTMLParser

No, it is not possible to do what you want. 不,不可能做您想做的事。 the semantics of multiple except clauses covers catching different types of exceptions that may be thrown from the same block of code . 多个except子句的语义涵盖了捕获可能从同一代码块引发的不同类型的异常。 You must nest the statements or rethink your code to get the desired results. 您必须嵌套语句或重新考虑您的代码才能获得所需的结果。

This might be a case where it would be better to test for the preconditions that you expect to cause an exception. 在这种情况下,最好测试一下您预期会导致异常的先决条件。

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

etc. 等等

I would also recommend against using catchall except: phrases except in very specialized circumstances where you know you need them. 我还建议您不要使用catchall except:在非常专业的情况下(除非您知道您需要它们),否则除外。

If you're doing the same or a similar thing in every try/except block, you might use a loop 如果在每个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

Of course it makes no sense in this form, because trying the same thing three times will yield the same result. 当然,这种形式没有任何意义,因为三遍尝试相同的事情将产生相同的结果。

You'd be better off restructuring your code: 您最好重组代码:

success = False

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

if not success:
   DOXYZ

It's better to explicitly specify the exception, though. 不过,最好明确指定异常。 Do you really want to catch KeyboardInterrupt s? 您真的要赶上KeyboardInterrupt吗?

I'd avoid the exceptions if I were doing this: 如果这样做,我会避免例外情况:

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM