Как мне использовать try ... кроме как при определении функции? - PullRequest
4 голосов
/ 01 апреля 2010

Я обнаружил, что меня смутила проблема, заключающаяся в том, что, когда мне не нужно использовать try..except. В последние несколько дней он использовался почти во всех определенных мной функциях, что я считаю плохой практикой. Например:

class mongodb(object):

    def getRecords(self,tname,conditions=''):
        try:
            col = eval("self.db.%s" %tname)
            recs = col.find(condition)
            return recs
        except Exception,e:
            #here make some error log with e.message

Я думал, что исключения могут возникать везде, и я должен использовать try, чтобы их получить. И у меня вопрос: является ли хорошей практикой использование его повсеместно при определении функций? Если нет, то есть ли для этого какие-либо принципы? Помощь будет принята с благодарностью!

Привет

Ответы [ 4 ]

5 голосов
/ 01 апреля 2010

Это может быть не лучшим решением. Единственное исключение состоит в том, что вы можете поймать их на совершенно ином уровне, чем он поднят. Лучше обращаться с ними там, где у вас достаточно информации, чтобы сделать что-то полезное с ними (это очень зависит от приложения и контекста).

Например, приведенный ниже код может выдать IOError («[Errno 2] Нет такого файла или каталога»):

def read_data(filename):
    return open(filename).read()

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

try:
    data = read_data('data-file.txt')
except IOError:
    data = read_data('another-data-file.txt')
    # or
    show_error_message("Data file was not found.")
    # or something else
5 голосов
/ 01 апреля 2010

Это (охватывая все возможные исключения очень широко) действительно считается плохой практикой. Вы замаскируете истинную причину исключения.

Поймать только ' с явно названными ' типами исключений (которые вы ожидаете, что и вы можете / изящно обработать) Позвольте остальным (неожиданным) пузыриться как следует.

Вы можете зарегистрировать эти (необученные) исключения (глобально), переопределив sys.excepthook:

import sys
import traceback
# ...

def my_uncaught_exception_hook(exc_type, exc_value, exc_traceback):
    msg_exc = "".join( \
              traceback.format_exception(exc_type, exc_value, exc_traceback) )
    # ... log here...

sys.excepthook = my_uncaught_exception_hook # our uncaught exception hook
4 голосов
/ 01 апреля 2010

Вы должны найти баланс между несколькими целями:

  1. Приложение должно самостоятельно восстанавливать как можно больше ошибок.

  2. Приложение должно сообщать обо всех неисправимых ошибках с достаточным количеством деталей, чтобы устранить причину проблемы.

  3. Ошибки могут возникать везде, но вы не хотите загрязнять свой код всем кодом обработки ошибок.

  4. Приложения не должны аварийно завершать работу

Чтобы решить # 3, вы можете использовать ловушку исключения . Все необработанные исключения приведут к прерыванию текущей транзакции. Поймать их на самом высоком уровне, откатить транзакцию (чтобы база данных не стала несогласованной) и либо выбросить их снова, либо проглотить (чтобы приложение не зависало). Вы должны использовать декораторы для этого . Это решает № 4 и № 1.

Решением для # 2 является опыт. Со временем вы узнаете, какая информация вам нужна для решения проблем. Сложная часть заключается в том, чтобы по-прежнему иметь информацию при возникновении ошибки. Одним из решений является добавление вызовов журнала отладки в низкоуровневые методы.

Другим решением является словарь на поток, в котором вы можете хранить некоторые биты и который вы выгружаете при возникновении ошибки.

1 голос
/ 01 апреля 2010

другой вариант - обернуть большой фрагмент кода в попытку: кроме: (например, в веб-приложении, одной конкретной странице GUI), а затем использовать sys.exc_info (), чтобы распечатать ошибку, а также стек, где это произошло

import sys
import traceback
try:
    #some buggy code    
    x = ??
except:
    print sys.exc_info()[0] #prints the exception class
    print sys.exc_info()[1] #prints the error message
    print repr(traceback.format_tb(sys.exc_info()[2])) #prints the stack
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...