Python 将方法调用作为变量传递给错误处理函数

Python 将方法调用作为变量传递给错误处理函数,python,beautifulsoup,Python,Beautifulsoup,尝试实现简单的错误处理,而不向代码中添加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对象(soup)的方法调用传递给通用的try/exce

尝试实现简单的错误处理,而不向代码中添加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对象(soup)的方法调用传递给通用的try/except函数

  • 尝试使用lambda,但理解不够,无法使用参数和汤
  • 看了部分,但没有看到如何称之为美丽的汤方法
  • 看 但我不知道汤是怎么传递的
我的代码:

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'

在达到if_error函数之前,soup.find方法一直激发。如何解决此问题?

您的问题是将soup.find()的结果传递给if\u error而不是函数。您可以尝试将实际函数传递给if_error,但我会这样做:

def findError(soup, arg1, arg2, error):
    try:
        return soup.find(arg1, arg2)
    except:
        return error
然后打电话:

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

像这样做怎么样

def if_error(f,f_args,fail_value):
    try:
      value = f(**f_args).text
    except:
      value = fail_value
    return value
其中,
f_args
是要传递给函数的参数的字典
f

这个怎么样:

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)

您需要为错误屏蔽函数提供几个项:要转换为默认值的异常、默认值、要调用的函数及其参数:

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'
42
-1
回溯(最近一次呼叫最后一次):
文件“test.py”,第13行,在
如果出现错误,则打印(TypeError,-2,test\u fn,“abc”)
文件“test.py”,第3行,如果出错
返回fn(*args,**kwargs)
文件“test.py”,第8行,在test\u fn中
返回整数(x)
ValueError:基数为10的int()的文本无效:“abc”

正如您所看到的,上一次调用让异常发生,因为我们没有用它捕获
ValueError
s。

在arg之后加上非关键字arg,代码
description=findError(soup,'div',attrs={'class':'listing_description\u module description'}',)
/更改为
description=findError(soup,'div,',{'class':'listing_description_module description'}',
/和findError函数
返回soup.find(arg1,attrs=arg2)
传递函数不仅在Python中是可能的,而且是受鼓励的。请查看Meitham的答案,以获得处理此问题的好方法。
attrs={}
?您有
查找错误
接受
arg1
arg2
、和
错误
,而不是
属性
。Meitham的解决方案将是您想要的sure@thagorn同意。迈瑟姆的解决方案以提问的方式回答了问题,通过了“a”fn。然而,你的解决方案在illus中很有用以一种简单易懂的方式为beautifulsoup量身定制了一个解决方案。太棒了!我终于明白了。这确实让函数在一个地方命名,在另一个地方执行。良好的可重用性。
arg\u dict={'name':'div','attrs':{'class':'listing\u description\u module description'}description=if\u error(soup.find,arg_dict.)
解决方案有效。比构建参数dict
description=if_error(soup.find,,'div',attrs={'class':'listing_description\u module description}更具可读性)
您可能已经知道这一点,但使用纯
except
是危险的做法,因为它会抓住几乎所有可能的问题。您应该提供您愿意转换为
if\u error
值的异常。