开发者

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)
开发者_JS百科            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.


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:

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.


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. 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.


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"


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 KeyboardInterrupts?


If you're doing the same or a similar thing in every try/except block, you might use a loop

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜