[英]Which exception should I raise on bad/illegal argument combinations in Python?
我想知道在 Python 中指示無效參數組合的最佳實踐。 我遇到過一些情況,你有這樣的功能:
def import_to_orm(name, save=False, recurse=False):
"""
:param name: Name of some external entity to import.
:param save: Save the ORM object before returning.
:param recurse: Attempt to import associated objects as well. Because you
need the original object to have a key to relate to, save must be
`True` for recurse to be `True`.
:raise BadValueError: If `recurse and not save`.
:return: The ORM object.
"""
pass
唯一的煩惱是每個包都有自己的,通常略有不同的BadValueError
。 我知道在 Java 中存在java.lang.IllegalArgumentException
- 是否很好理解每個人都會在 Python 中創建自己的BadValueError
或者是否有另一種首選方法?
我只會提高ValueError ,除非您需要更具體的異常..
def import_to_orm(name, save=False, recurse=False):
if recurse and not save:
raise ValueError("save must be True if recurse is True")
做class BadValueError(ValueError):pass
真的沒有意義——你的自定義類在使用上與ValueError相同,那么為什么不使用它呢?
我會從ValueError
繼承
class IllegalArgumentError(ValueError):
pass
有時最好創建自己的異常,但從內置異常繼承,這盡可能接近您想要的。
如果您需要捕獲該特定錯誤,擁有一個名稱會很有幫助。
我認為處理這個問題的最好方法是 python 本身處理它的方式。 Python 引發了一個 TypeError。 例如:
$ python -c 'print(sum())'
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: sum expected at least 1 arguments, got 0
我們的初級開發人員剛剛在谷歌搜索“python 異常錯誤參數”中找到了這個頁面,我很驚訝自問這個問題以來的十年里,沒有人提出明顯的(對我來說)答案。
這取決於參數的問題是什么。
如果參數的類型錯誤,則引發 TypeError。 例如,當您獲得一個字符串而不是那些布爾值之一時。
if not isinstance(save, bool):
raise TypeError(f"Argument save must be of type bool, not {type(save)}")
但是請注意,在 Python 中我們很少進行這樣的檢查。 如果參數確實無效,一些更深層次的函數可能會為我們抱怨。 如果我們只檢查布爾值,也許某些代碼用戶稍后會向它提供一個字符串,因為知道非空字符串始終為 True。 這可能會為他節省一個演員。
如果參數具有無效值,則引發 ValueError。 這似乎更適合您的情況:
if recurse and not save:
raise ValueError("If recurse is True, save should be True too")
或者在這種特定情況下,遞歸的真值意味着保存的真值。 由於我認為這是從錯誤中恢復,您可能還想在日志中抱怨。
if recurse and not save:
logging.warning("Bad arguments in import_to_orm() - if recurse is True, so should save be")
save = True
我主要只是看到在這種情況下使用的內置ValueError
。
在這種情況下,您很可能會使用ValueError
( raise ValueError()
in full),但這取決於錯誤值的類型。 例如,如果您創建了一個只允許字符串的函數,而用戶輸入的是一個整數,那么您將使用TypeError
。 如果用戶輸入了錯誤的輸入(意味着它具有正確的類型但不符合某些條件),則Value Error
將是您的最佳選擇。 Value
Error 也可用於阻止程序發生其他異常,例如,您可以使用ValueError
來阻止 shell 表單引發ZeroDivisionError
,例如,在此函數中:
def function(number):
if not type(number) == int and not type(number) == float:
raise TypeError("number must be an integer or float")
if number == 5:
raise ValueError("number must not be 5")
else:
return 10/(5-number)
PS 有關 python 內置異常的列表,請轉到此處: https : //docs.python.org/3/library/exceptions.html (這是官方 python 數據庫)
我不確定我是否同意從ValueError
繼承——我對文檔的解釋是ValueError
只應該由內置函數引發……從它繼承或自己引發似乎不正確。
當內置操作或函數接收到類型正確但值不合適的參數時引發,並且這種情況沒有用更精確的異常(如 IndexError)描述。
同意 Markus 的建議,推出您自己的例外,但例外的文本應闡明問題出在參數列表中,而不是單個參數值中。 我建議:
class BadCallError(ValueError):
pass
當缺少特定調用所需的關鍵字參數,或參數值單獨有效但彼此不一致時使用。 當特定參數是正確類型但超出范圍時, ValueError
仍然是正確的。
這不應該是 Python 中的標准異常嗎?
一般來說,我希望 Python 風格在區分函數的錯誤輸入(調用者的錯誤)和函數中的錯誤結果(我的錯誤)方面更加清晰。 所以也可能有一個 BadArgumentError 來區分參數中的值錯誤和局部變量中的值錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.