2012-05-28 74 views
1

所以我碰到了這個有趣的問題來了,同時審查代碼:斷言包裝函數

class Foo: 

    def __init__(self, foo_name): 
    self.foo_doo = getattr(foo_name, 'foo_lists', None) 

    def assert_foo(self, varname): 
    assert hasattr(self, 'foo_%s' % varname) 

    def foobar(self): 
    assert_foo('doo') 

想知道包裹斷言你自己的定製版本更快/更好的解決方案,然後使用assert hasattr(...)每次你需要確保屬性存在而不是無?

+1

沒有什麼特別的原因你不能''unittest'有一些像'assertEqual'這樣的包裝器。這取決於什麼使你的代碼最具可讀性。 –

+2

更快?快點打字,當然。顯然,執行速度較慢,因爲涉及到一個額外的函數調用。 – kindall

+3

我同意@ThomasK,我沒有看到任何問題。至於速度,我認爲在大多數情況下(儘管@kindall指出了理論差異),這應該可以忽略不計,具體取決於您執行此代碼的頻率。 – ubik

回答

2

除非變爲

self.assert_foo('doo') 

這且不說,我不認爲應該assert在上面的代碼中使用帶或不帶包裝的最後一行將提高NameError。正確的行只檢查self.foo_doo集,但不是它不是None

if self.foo_doo is not None: 

兩者兼而有之。

如果想縮寫查找第一個屬性檢查,一個可以寫

def has_foo(self, name): 
    return hasattr(self, 'foo_'+name) 

def foobar(self): 
    if has_foo('doo'): 

如果您還希望非None檢查,改變has_foo回:

return getattr(self, 'foo_'+name, None) is not None 

除此之外,生產代碼中的assert應僅用於檢查內部邏輯,而不是用於代碼用戶影響的運行時條件。用戶可以刪除或禁用斷言,所以一旦釋放,代碼不應該依賴斷言它的正確操作。

在上面的代碼中,__init__設置self.foo_doo東西,但調用者可以隨後刪除該屬性。所以屬性的存在和價值都是由用戶確定的運行時間條件,而不是斷言的適當主體。

TestCase.assertXxx方法unittest只用於測試,當它們失敗時,它們不僅僅包裝簡單的assert