2012-01-19 9 views
2

試圖在不添加buku try/except語句的情況下實現簡單的錯誤處理。將方法調用作爲變量傳遞給錯誤處理函數

我的if_error函數試圖模擬excel中的iferror(value,value_if_error)公式。

If the value (another formula) is valid, 
    return its resulting value 
else 
    return value_if_error 

I /如何傳遞一個方法調用從beautifulsoup對象(湯)與參數,以通用的嘗試,除了功能?

  • 試過lambda,但沒有足夠的理解,使其與參數&湯的工作。
  • 看着偏,但沒有看到如何會叫美麗的湯方法
  • 看着this 卻沒有看到湯將如何傳遞?

我的代碼:

def if_error(fn,fail_value): 
    try: 
     value = fn 
    except: 
     value = fail_value 
    return value 

def get_trulia_data(soup): 
    d = dict() 

    description = if_error(soup.find('div', attrs={'class': 'listing_description_module description'}).text,'') 

    sale_price = if_error(soup.find('div', attrs={'class': 'price'}).text,'0') 
    sale_price = re.sub('[^0-9]', '', sale_price) 

    details = if_error(soup.find('ul', attrs={'class': 'listing_info clearfix'}),'') 

    bed = if_error(soup.find('input', attrs={'id': 'property_detail_beds_org'})['value'],'') 
    bath = if_error(soup.find('input', attrs={'id': 'property_detail_baths_org'})['value'],'') 

    ... 

    return d 

錯誤:

Traceback (most recent call last): 
data_dict = get_trulia_data(url) 
description = if_error(soup.find('div', attrs={'class': 'listing_description_module description'}).text,'') 
AttributeError: 'NoneType' object has no attribute 'text' 

的soup.find方法保持達到if_error功能之前發射。我怎樣才能解決這個問題?

+0

您可能已經知道這一點,但使用裸「except」是一種危險的做法,因爲它可以捕捉到幾乎所有可能的問題。您應該提供您願意轉換爲'if_error'值的異常。 –

回答

1

如何:

def if_error(fn, fail_value, *args, **kwargs): 
    try: 
     return fn(*args, **kwargs) 
    except: 
     return fail_value 

def test_fail(x): 
    raise ValueError(x) 

def test_pass(x): 
    return x 

if __name__=='__main__': 
    print if_error(test_fail, 0, 4) 
    print if_error(test_pass, 0, 5) 
+0

解決方案有效。稍微比構建一個參數更可讀dict'description = if_error(soup.find,'','div',attrs = {'class':'listing_description_module description'})' – mitrebox

0

你的問題是你正在將soup.find()的結果傳遞給if_error而不是該函數。這是可能的,你可以嘗試通過實際的功能if_error但我會做到這一點,而不是:

def findError(soup, arg1, arg2, error): 
    try: 
     return soup.find(arg1, arg2) 
    except: 
     return error 

,然後調用:

約做這樣的事情
findError(soup, 'div', attrs={}, '') 
+0

arg後的非關鍵字arg與代碼 /description = findError(soup,'div',attrs = {'class':'listing_description_module description'},'') /更改爲description = findError ,'div',{'class':'listing_description_module description'},'')' /和findError函數到 'return soup.find(arg1,attrs = arg2)' – mitrebox

+0

傳遞函數不僅可能在Python,這是鼓勵。查看Meitham的答案,以解決這個問題。 –

+0

'attrs = {}'有什麼意義?你有'findError'接受'soup','arg1','arg2'和'error',bot不是'attrs'。 –

0

什麼?

def if_error(f,f_args,fail_value): 
    try: 
     value = f(**f_args).text 
    except: 
     value = fail_value 
    return value 

其中f_args是你想傳遞給你的函數f參數的字典。

+0

甜!我終於明白這一點。這確實有效地在一個地方命名一個函數並在另一個地方執行它。良好的可重用性。 'arg_dict = {'name':'div','attrs':{'class':'listing_description_module description'}} description = if_error(soup.find,arg_dict,'')' – mitrebox

0

你要提供幾個項目到你的錯誤掩蔽功能:要轉換爲默認值例外,默認值,函數調用,和它的參數:

def if_error(exceptions, fail_value, fn, *args, **kwargs): 
    try: 
     return fn(*args, **kwargs) 
    except exceptions: 
     return fail_value 

def test_fn(x): 
    return int(x) 

if __name__=='__main__': 
    print if_error(ValueError, 0, test_fn, '42') 
    print if_error(ValueError, -1, test_fn, 'abc') 
    print if_error(TypeError, -2, test_fn, 'abc') 

這給了我們:

42 
-1 
Traceback (most recent call last): 
    File "test.py", line 13, in <module> 
    print if_error(TypeError, -2, test_fn, 'abc') 
    File "test.py", line 3, in if_error 
    return fn(*args, **kwargs) 
    File "test.py", line 8, in test_fn 
    return int(x) 
ValueError: invalid literal for int() with base 10: 'abc' 

正如你所看到的,LA st電話讓異常提升,因爲我們沒有捕捉到ValueError

相關問題