2011-05-23 77 views
4

我不太清楚如何在Python中正确使用异常。我想处理我无法完全信任的数据(它们很容易发生变化,如果它们发生变化,脚本可能会中断)。假设我使用BeautifulSoup处理网页。如果网站的作者对他的网站进行了一些更改,有些声明可能会引发异常。让我们来看看这个代码示例:现在如何正确处理异常?

data = urllib2.urlopen('http://example.com/somedocument.php').read() 
soup = BeautifulSoup(data, convertEntities="html") 

name = soup.find('td', text=re.compile(r'^Name$')).parent.nextSibling.string 

print name 

,如果soup.find()失败,因为该网站的所有者将改变网站的内容,并重新命名细胞NameNames,异常AttributeError: 'NoneType' object has no attribute 'parent'将得到提升。但我不介意!我预计有些数据将不可用。我只是想继续和使用哪些变量我有可用的(当然也会有一些数据我所需要的,如果它们是不可用的我就干脆退出

我想出唯一的办法就是:

try: name = soup.find('td', text=re.compile(r'^Name$')).parent.nextSibling.string 
except AttributeError: name = False 
try: email = soup.find('td', text=re.compile(r'^Email$')).parent.nextSibling.string 
except AttributeError: email = False 
try: phone = soup.find('td', text=re.compile(r'^Phone$')).parent.nextSibling.string 
except AttributeError: phone = False 

if name: print name 
if email: print email 
if phone: print phone 

有没有什么更好的方法,或者我应该继续作出尝试,不同的是每类似的声明它没有看起来非常漂亮,在所有

编辑:?对我来说最好的解决办法是这样的:

try: 
    print 'do some stuff here that may throw and exception' 
    print non_existant_variable_that_throws_an_exception_here 
    print 'and few more things to complete' 
except: 
    pass 

这样会很好,但pass会跳过try代码块中的任何内容,因此and few more things to complete将不会被打印。如果出现类似通过的情况,但它会忽略错误并继续执行,那就太好了。

+0

使用'finally'。 http://docs.python.org/tutorial/errors.html#defining-clean-up-actions – sdolan 2011-05-23 23:47:01

+0

“pass会跳过try代码块中的任何内容”。正确。为什么在'try:'块中放置这么多语句? – 2011-05-24 00:40:37

回答

4

首先,如果你不介意的异常你可以让它通过:

try: 
    something() 
except AttributeError: 
    pass 

,但从来没有做到这这是会让所有错误传:

try: 
    something() 
except Exception: 
    pass 

至于你的代码示例,也许它可以用这样的东西整理:

myDict = {} 

for item in ["Name", "Email", "Phone"]: 
    try: 
     myDict[item] = soup.find('td', text=re.compile(r'^%s$' % item)).parent.nextSibling.string 
    except Attribute 
     myDict[item] = "Not found" 

for item in ["Name", "Email", "Phone"]: 
    print "%s: %s" % (item, myDict[item]) 
+0

感谢您的建议第一个建议。如果我没有弄错,它应该是'except'而不是'catch'。但无论如何,看看我编辑的问题。至于第二个建议,我理解我的例子是合理的,使用字典和做你喜欢的东西。但这仅仅是一个例子,我认为这对我来说不会奏效。我宁愿只是检查变量是否可用并使用它,如果没有,则继续。 – Gargauth 2011-05-23 23:43:37

+0

噢,哎呀,我猜我匆忙。 :-( – nakedfanatic 2011-05-23 23:47:40

1

您是否尝试过使用try/finally语句呢?从文档

http://docs.python.org/tutorial/errors.html#defining-clean-up-actions

例子:

>>> def divide(x, y): 
...  try: 
...   result = x/y 
...  except ZeroDivisionError: 
...   print "division by zero!" 
...  else: 
...   print "result is", result 
...  finally: 
...   print "executing finally clause" 

所以,用你的例子:

try: 
    do_some_stuff_here_that_may_throw_an_exception() 
except someError: 
    print "That didn't work!" 
else: 
    print variable_that_we_know_didnt_throw_an_exception_here 
finally: 
    print "finishing up stuff" 

“终于” 永远excecute,所以这就是你可以把你的“完成“的东西。