Передача вызова метода в качестве переменной в функцию обработки ошибок - PullRequest
2 голосов
/ 20 января 2012

Попытка реализовать простую обработку ошибок, не добавляя в мой код инструкции bucu try / Кроме операторов.

Моя функция if_error пытается эмулировать формулу iferror (value, value_if_error) в excel.

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

Как передать вызов метода из объекта Beautifulsoup (супа) с параметрами в общую функцию try / кроме?

  • Попробовал лямбду, но не понял достаточночтобы он работал с параметрами и супом.
  • Посмотрел на Частичное, но не видел, как это вызвало бы метод прекрасного супа
  • Посмотрел на это , но не видел, как будет проходить суп?

Мой код:

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.Как я могу это исправить?

Ответы [ 4 ]

1 голос
/ 20 января 2012

Как насчет этого:

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 голосов
/ 20 января 2012

Вам потребуется указать несколько элементов для функции маскирования ошибок: исключения, которые вы хотите преобразовать в значение по умолчанию, значение по умолчанию, вызываемую функцию и ее аргументы:

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 s с ним.

0 голосов
/ 20 января 2012

Как насчет того, чтобы сделать что-то подобное?

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

где f_args - словарь аргументов, которые вы хотите передать своей функции f.

0 голосов
/ 20 января 2012

Ваша проблема заключается в том, что вы передаете результат функции sou.find () в if_error вместо функции.Возможно, вы могли бы попробовать передать фактическую функцию в if_error, но я бы сделал это вместо этого:

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

и затем вызвал бы:

findError(soup, 'div', attrs={}, '')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...