2008-12-15 60 views
15

我對在他們編寫的Python中進行多少前期驗證感興趣。我應該在我的python函數/方法上做多少輸入驗證?

下面是簡單的功能的幾個例子:

def factorial(num): 
    """Computes the factorial of num.""" 

def isPalindrome(inputStr): 
    """Tests to see if inputStr is the same backwards and forwards.""" 

def sum(nums): 
    """Same as the built-in sum()... computes the sum of all the numbers passed in.""" 

如何徹底你開始計算前檢查輸入值,你怎麼做你檢查?如果輸入錯誤(例如,在同一模塊中定義BadInputException),你會拋出某種專有的異常嗎?你剛開始你的計算,並且如果壞數據被傳入(例如,「asd」爲factorial),它會在某個時候拋出一個異常?

當傳入的值應該是一個容器,你不僅檢查容器,但它的內部的所有值?

像factorial這樣的情況,傳入的內容可能會轉換爲int(例如float),但是如果這樣做可能會失去精度?

回答

6

對於像sum,factorial等計算,pythons內置類型檢查將會很好。這些計算將結束upp呼叫add,mul等等的類型,如果它們中斷,它們會拋出正確的異常。通過執行自己的檢查,您可能會使其他工作輸入無效。

4

我基本上試圖將變量轉換爲它應該是的,並傳遞或拋出適當的異常,如果失敗。

def factorial(num): 
    """Computes the factorial of num.""" 
    try: 
     num = int(num) 
    except ValueError, e: 
     print e 
    else: 
     ... 
+5

我不想打印任何東西。無論是單獨拋出異常還是提出其他的東西。印刷會令人困惑。 – 2008-12-15 11:27:47

2

這取決於我正在寫什麼,以及輸出如何到達那裏。 Python沒有其他OO語言的公/私保護。相反,有約定。例如,外部代碼只應該調用沒有用下劃線作爲前綴的對象方法。因此,如果我正在編寫一個模塊,我會驗證任何不是從我自己的代碼生成的任何內容,即任何對公共訪問的方法/函數的調用。有時候,如果我知道的驗證是昂貴的,我讓togglable用kwarg:當代碼熄滅的發展和投入生產

def publicly_accessible_function(arg1, validate=False): 
    if validate: 
    do_validation(arg1) 
    do_work 

內部方法可以做到通過assert語句,它可以完全禁用驗證。

5

我想寫docstring說明預期和接受什麼類型的參數,我沒有明確地在我的函數中檢查它。

如果有人想使用我的功能與任何其他類型的責任,以檢查他的類型是否模仿我的接受不錯。也許你的factorial可以和一些自定義的long-like類型一起使用,以獲得你不會想到的東西?或者,也許你的總和可以用來連接字符串?爲什麼你應該通過類型檢查來禁止它?無論如何,這不是C。

10

assert什麼是絕對必要的。

重要提示:什麼是絕對是必不可少的。有些人過分考驗了一些東西。

def factorial(num): 
    assert int(num) 
    assert num > 0 

不完全正確。長期也是合法的可能性。

def factorial(num): 
    assert type(num) in (int, long) 
    assert num > 0 

更好,但仍不完美。許多Python類型(如有理數,或類似數字的對象)也可以在良好的階乘函數中工作。很難斷言一個對象具有基本的整數類屬性,而不會過於具體,並且會消除將來不想考慮的類。

我從不爲每個函數定義唯一的例外。我爲重要的模塊或包定義了一個唯一的例外。然而,通常,只是一個Error類或類似的東西。這種方式應用程序說except somelibrary.Error,e:這是關於所有你需要知道的。細粒度的異常變得繁瑣而愚蠢。

我從來沒有這樣做,但我可以看到可能有必要的地方。

assert all(type(i) in (int,long) for i in someList) 

但是,通常情況下,普通的Python內置類型檢查工作正常。他們幾乎可以找到幾乎所有時間都非常重要的特殊情況。當某些東西不是正確的類型時,Python會引發TypeError,它總是指向正確的代碼行。

順便說一句。如果我絕對確信該功能會被濫用,我只會在設計時添加斷言。稍後當我有一個單調測試失敗時,我有時會添加斷言。

+0

>當某些東西不是正確的類型時,Python引發一個TypeError,它總是指向正確的代碼行。 這不完全正確。如果你的函數正在對之前設置的一些實例數據執行操作,那麼確定爲什麼值是錯誤的類型會是非常具有挑戰性的。 – Nathan 2010-10-14 10:06:07

1

我幾乎從來沒有執行過任何一種檢查,除非我認爲有人可能會認爲他們可以傳遞一些會產生完全瘋狂結果的X.

另一次我檢查的時候,我接受幾個類型的參數,例如一個函數,接受一個列表,可能會接受一個任意的對象,只是將其包裝在一個列表中(如果它不是一個列表)。所以在這種情況下,我會檢查類型 - 不要執行任何操作 - 僅僅是因爲我希望函數在使用方式上具有靈活性。

0

只打擾檢查你是否有失敗的單元測試,迫使你。

也考慮「EAFP」......這是Python的方式!

0

關於另一種語言如何處理它可能會增加一些價值。對於Perl,我記得使用這個模塊 - http://search.cpan.org/dist/Params-Validate/,它從開發人員卸載了大量的參數驗證。我正在尋找類似的東西在Python中碰到這個:http://www.voidspace.org.uk/python/validate.html我還沒有嘗試過。但是我猜想在整個代碼庫中驗證參數的標準方法可以在整個團隊中預先設置參數驗證期望值。

相關問題