在Python中驗證構造函數參數的最佳實踐方法是什麼?在Python中驗證構造函數參數
我是新來的語言,並且正在使用raise
:
class Breakfast(object):
def __init__(self, spam=None, eggs=0):
if not spam:
raise Error("Error: no spam")
這是愚蠢的,還是什麼?
謝謝!
在Python中驗證構造函數參數的最佳實踐方法是什麼?在Python中驗證構造函數參數
我是新來的語言,並且正在使用raise
:
class Breakfast(object):
def __init__(self, spam=None, eggs=0):
if not spam:
raise Error("Error: no spam")
這是愚蠢的,還是什麼?
謝謝!
如果您只是想確保傳遞所需的參數,那麼請忽略默認值。如果參數丟失,Python會自動拋出一個TypeError。
def __init__(self, spam, eggs=0)
如果參數不是可選的,爲什麼你要爲它提供默認參數?如果沒有傳遞一個默認值的參數,Python解釋器會自動產生一個錯誤。
在這種特殊情況下,不要讓垃圾郵件關鍵字:
class Breakfast(object):
def __init__(self, spam, eggs=0):
"""Spam may not be none.
"""
# This is just validation of parameters which you can either
# do or leave. spam is part of the contract now and you documented
# that it may not be None
if not spam:
raise Error("Error: spam may not be None")
在您的具體的例子這將是最簡單的不給spam
默認值 - 那麼Python將診斷如果用戶忘記傳遞該參數,那麼問題在於你。 (但是,通過False
,0
,[]
,... as spam
對於Python來說可以,所以如果你有對他們的需求,你可能需要另外指定你自己的語義檢查)。
如果您必須執行任何診斷,則在發生異常時引發異常是明智的。然而,它應該是適當的例外 - 例如,如果該值是可接受的類型但不能被接受爲特定值,並且具有清晰,完整的消息,則爲ValueError
。所以,總結:
class Breakfast(object):
def __init__(self, spam, eggs=0):
if not spam:
raise ValueError("falsish spam %r not acceptable" % (spam,))
(你需要包裝spam
在單項元組(spam,)
這裏,否則傳遞一個空的元組爲spam
將導致複雜的,令人困惑的錯誤;-)。
謝謝 - 我沒有意識到使用格式化字符串時需要考慮到這一點。 – mikewaters 2010-07-21 18:55:09
@threecheese,不客氣 - 我完全明確地提到它,因爲我知道人們往往不去想它;-)。 – 2010-07-21 20:46:11
首先,我想你的意思
if spam is None:
爲Breakfast(0)
將布爾真爲not spam
的將是[]
的說法,0.0
,''
,u''
等
其次,錯誤提出既是一個無信息的泛型類,而是一個更典型的ValueError
。最後,例外文本可以提供更多信息,並引導呼叫者進行修復。
而且,正如其他人所指出的那樣,您通過設置一個不存在的默認值來犧牲自動檢查。
如果它不是關鍵字,是否仍然可以將它作爲關鍵字傳遞? (例如b = Breakfast(spam ='ham')) – mikewaters 2010-07-21 18:53:36
@threecheeseopera不,我不這麼認爲。 – extraneon 2010-07-22 09:28:11