2011-05-23 118 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,所以這就是你可以把你的「完成「的東西。