2016-03-12 41 views
0

可以說,我有一個函數:如何讓python函數返回異常追溯或結果?

def ReadFile(): 
    with open("/etc/passwd") as file: 
     data = file.read() 

該功能可能會成功,在這種情況下,需要返回的結果,也可能會失敗,在這種情況下,我想回到例外的回溯其會通過電子郵件發送給我,所以我知道我的程序中出現了一些問題,並且確切地說失敗了。

要做到這一點,我可以這樣做:

import traceback 

def ReadFile(): 
    try: 
     with open("/etc/passwd") as file: 
      data = file.read() 
    except IOError: 
     return traceback.format_exc() 
    return data 

如果它能夠成功地讀取該文件,則返回文件的內容。否則,它會返回異常的回溯。

traceback.format_exc()返回一個字符串。如果ReadFile()應該返回一個列表,或者如果成功則返回一個元組或整數,比事情很簡單 - 當你調用ReadFile()時,如果返回的結果是一個字符串,那麼你知道它失敗了,你可以運行代碼,你的錯誤,如果結果是你期望的類型(int,tuple,list或w/e),那麼你知道它的工作。

如果在我的示例中,ReadFile()應該返回一個字符串,而不是確定ReadFile()成功或失敗會變得困難得多,因爲您需要解析字符串以確定它是否看起來像如追溯或您預期的結果。

有沒有更好的方法來做到這一點?也許某種方式可以追溯返回某些具有與traceback.format_exc()包含的信息相同的信息的對象,以便更容易確定ReadFile()是成功還是失敗?

+5

更好的辦法是讓它拋出並在通話現場捕捉異常。這是例外情況。 –

回答

3

我建議,而不是捕獲這個方法中的異常,讓它引發一個異常並從你所調用的任何地方捕獲異常。

換句話說,不要把你的try catch放在那個方法中。把try catch放在任何調用該方法的地方,然後抓住它可能會提出的東西。

所以,有這個代替:

import traceback 

def ReadFile(): 
    with open("/etc/passwd") as file: 
     data = file.read() 
    return data 

try: 
    r = ReadFile() 
except IOError: 
    traceback.format_exc() 
    # or log or whatever operation 

或者,如果你真的想保持你的異常在方法處理,並希望返回某種「失敗」信號,那麼你或許應該回到例外對象,而是看看它是否存在。

所以,你也可以這樣做。當你調用你的方法來查看是否有異常時,請返回Exception對象。

def ReadFile(): 
    try: 
     with open("/etc/passwd") as file: 
      data = file.read() 
    except IOError as exc: 
     return exc 
    return data 

if isinstance(r, Exception): 
    # do exception things here 

雖然我會選擇第一個選項。

+0

由於所有的答案和伊斯梅爾的評論,我現在得到,我不應該在我的函數內捕獲異常,但抓住它的外部。謝謝你們 - 不能相信這件事不會發生在我身上。出於好奇,如果我確實返回了異常對象本身,是否有任何方法從它讀取回溯信息?或者這不是它存儲的東西? – Tal

+0

'format_exc()'讓你回溯。閱讀這裏,有更多的信息,可以給你更多的上下文,瞭解如何實現你正在尋找的內容:http://stackoverflow.com/a/12539332/1832539 – idjaw

+0

酷 - 我只是想知道是否有可能 - 顯然這是 - 感謝鏈接。到目前爲止,選項1對我來說非常棒 - 它大大簡化了我的代碼。 – Tal

2

異常已經「返回」到封閉範圍,這就是爲什麼異常存在的全部原因。

# See how simple this is? 
def read_file(): 
    with open('/etc/passwd') as file: 
     return file.read() 

然後,處理異常在調用鏈中的適當位置,但僅適當的位置。對於想要以特定方式處理的預期異常,請在有足夠信息正確處理它們的地方處理它們。對於一般的例外情況,請在頂級事件循環中處理它們,或者直接傳播它們並讓解釋器將它們打印出來。

與大多數其他事情一樣,您希望處理異常的確切方式因程序而異。但是,將異常作爲函數結果返回會適得其反。

2

如果要返回異常對象,你可以這樣做:

def ReadFile(): 
    try: 
     with open("/etc/passwd") as file: 
      data = file.read() 
    except IOError as ex: 
     return ex 
    return data 

然而,隨着伊斯梅爾說,它能夠更好地讓它拋出異常喜歡

def ReadFile(): 
    with open("/etc/passwd") as file: 
     return file.read() 

... # Some code that eventually calls the function 
... 
try: 
    data = ReadFile() 
except IOError: 
    print("File read failed") 
    ... # Handle error