2012-01-19 13 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 

パラメータを持つbeautifulsoupオブジェクト(スープ)から汎用のtry/except関数にメソッド呼び出しを渡すにはどうすればよいですか?

  • 試したラムダが、パラメータ&スープで動作するのに十分理解していませんでした。
  • 部分に見えたが、それは美しいスープ方法
  • 呼び出す方法表示されませんでしたが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

ソリューションが動作します。引数を作成するより少し読みやすい 'description = if_error(soup.find、 ''、 'div'、attrs = {'class': 'listing_description_module description'})' – mitrebox

0

あなたの問題は、関数の代わりにsoup.find()の結果をif_errorに渡すことです。

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

をしてから呼び出します:

findError(soup, 'div', attrs={}, '') 
+0

キーワード以外の引数argの後にコード を入れてください。description = findError(スープ、 'div'、attrs = {'クラス': 'listing_description_module description'}、 '') ' /description = findError(スープ、 'DIV' { 'クラス': 'listing_description_module記述'} '') ' /及びfindError機能 '戻りsoup.find(ARG1、ATTRS = ARG2)に ' – mitrebox

+0

渡す機能は、だけでなく可能ですPython、それは奨励されています。これを処理する良い方法については、Meithamの回答を参照してください。 –

+0

'attrs = {}'のポイントは何ですか? 'findError'は、' soup'、 'arg1'、' arg2'、 'error'を受け取り、' attrs'ではなく 'bot'です。 –

0

何このような何かをやって、それはあなたがif_errorする実際の関数を渡す試みることができるが、私は代わりにこれを行うだろうている可能性がありますか? f_argsはあなたの機能fに渡す引数の辞書がある

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

。これについて

+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' 

をあなたが見ることができるように、ラ私たちがValueErrorを捕まえていなかったので、stコールは例外を発生させました。

関連する問題