簡體   English   中英

Python異常處理 - 如何做到pythonic?

[英]Python exception handling - How to do it pythonic?

我還在學習Python programmimg語言。 我在代碼異常方面問自己,當需要以pythonic方式處理這種情況時。 我讀了幾遍“你永遠不應該默默地傳遞錯誤”。

例如一個小功能:

def square(list_with_items):
    return [i**2 for i in list_with_items]

如果有人將元組作為參數傳遞,是否需要編寫錯誤處理程序? 或者,當我必須檢查用戶輸入的驗證時,它更有意義嗎?

在檢查類型的特定情況下,“Pythonic”要做的就是不檢查它們。 除非有充分的理由,否則你應該假設呼叫者傳遞的是合理類型(注意:“明智的類型”可能與“你期望的類型”不同),並盡力返回合理的東西。 如果呼叫者傳遞的是一種不合理的類型,那么讓他們處理后果是完全可以接受的。

例如,有人可能明智地將Decimal數字的迭代器傳遞給square函數:

>>> from decimal import Decimal
>>> square(Decimal(line.strip()) for line in open("numbers.txt")
[Decimal("4.0"), Decimal("9.0"), ...]

一切都會奏效! 但明確檢查類型會使該用例更加困難。

然后,例如,如果有人傳遞了一些不合理的東西,他們就可以處理錯誤:

>>> square(42)
…
TypeError: 'int' object isn't iterable

此錯誤消息還將(在腳本中)包含調試問題所需的所有文件名和行號。

另一方面,當調用者可能會出現令人驚訝的后果時,顯式檢查參數有時很有用。 例如,如果你正在編寫一個函數,它會在list表現出非常糟糕的性能,因為它需要deque ,那么檢查if not isinstance(input, deque): raise TypeError("a deque must be used!")可能是有道理的。

這種“處理類型的方法”的名稱叫做Duck Typing

你可以使用一個斷言:

def square(list_with_items):
    assert(all([type(x) == int for x in list_with_items]))
    return [i**2 for i in list_with_items]

你可以使用兩個斷言:

def square(list_with_items):
    assert(type(list_with_items) in (list, tuple))
    assert(all([type(x) == int for x in list_with_items]))
    return [i**2 for i in list_with_items]

你可以使用斷言和try / catch:

def square(list_with_items):
    assert(type(list_with_items) in (list, tuple))
    try:
        return [i**2 for i in list_with_items]
    except TypeError:
        raise Exception("Each element of the argument must be a number.")

這取決於。 在該具體示例中,如果您要以“只讀”的方式使用“square”的返回值,則不應該有一個“真正的錯誤”將元組作為參數傳遞。 這是因為即使元組是不可變的,你的函數也會返回一個帶有第一個元素的平方的新元組。

無論如何,我建議你使用一個簡單的if-else語句來更精確地避免問題(例如:如果你將來以不同的方式調用這個函數):

def square(list_with_items):
    if isinstance(list_with_items, list): # True if list_with_items is a list - False otherwise
        return [i**2 for i in list_with_items]
    else:
        return 'Error: type(list_with_items) must be a list!'

編輯:如果您願意(如果您要使用try-except語句捕獲異常),則可以在else語句中使用“raise Exception”:

else:
    raise Exception('Error: type(list_with_items) must be a list!')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM