Повторяющиеся попытки и исключения
Я создал кучу функций, и мне нужно очень похожие исключения, кроме всех, но мне не нравится иметь столько строк try и except clauses и один и тот же код внутри каждой функции. Например:
import sys
import random
def foo():
num=random.random()
try:
if num>0.5: print 'OK'
elif num>0.25: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
def bar():
num=random.random()
try:
if num>0.8: print 'OK'
elif num>0.6: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
Код после "try" отличается для функций, но код после "except" одинаковый. Я хочу консолидировать эти исключения, чтобы они не заставляли мой код выглядеть настолько стесненным. Есть ли хороший способ сделать это?
Ответы
Ответ 1
Декораторы Python - это то, что вы хотите.
Вы сказали, что блок исключений всегда один и тот же. Сделайте собственный декоратор, который делает то, что вы хотите. Вы должны применить это к каждой функции/методу, но он обязательно сохранит дублирование.
def handleError(function):
def handleProblems():
try:
function()
except Exception:
print "Oh noes"
return handleProblems
@handleError
def example():
raise Exception("Boom!")
При вызове метода с применением декоратора:
>>>
>>> example()
Oh noes
>>>
Вам нужно будет изменить типы исключений, а также то, что вы делаете, но вы получаете сумасшествие, где я собираюсь с этим.
Ответ 2
Содержимое внутри вашего блока try
- это интересный материал, поэтому он должен быть в функциях. Затем просто выберите нужную функцию и вызовите ее, завернутую за исключениями. Вы даже можете написать код исключения как функцию и передать выбранную функцию в качестве аргумента. например.
def foo():
num=random.random()
if num>0.5: print 'OK'
elif num>0.25: raise NameError('Too Small')
else: raise KeyboardInterrupt
def bar():
num=random.random()
if num>0.8: print 'OK'
elif num>0.6: raise NameError('Too Small')
else: raise KeyboardInterrupt
def try_numerics(f):
try:
f()
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
# In your main code...
if (need_to_run_foo):
try_numerics(foo)
elif (need_to_run_bar):
try_numerics(bar)
Ответ 3
Ответ выше не применим для функций, которые принимают аргументы - для более позднего случая, я думаю, вы хотели бы что-то вроде этого:
def handleError(f):
def handleProblems(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception:
print "Oh noes"
return handleProblems
Мы можем проверить его так:
@handleError
def addTwo(x, y):
print(x + y)
>>> addTwo(5,5)
10
>>> addTwo(5, 's')
Oh noes
Ответ 4
Если это ваши фактические функции, было бы легко их обобщить.
Вы можете создать одну общую функцию
def general(bottom_num, top_num):
num=random.random()
try:
if num>top_num: print 'OK'
elif num>bottom_num: raise NameError('Too Small')
else: raise KeyboardInterrupt
except NameError:
print "%s had a NameError" % sys._getframe().f_code.co_name
except:
print "%s had a different Error" % sys._getframe().f_code.co_name
это не позволит повторить код и повторить попытку: except: issue
Ответ 5
Недавно я столкнулся с одним и тем же сценарием, в моем случае у меня есть некоторые пользовательские исключения, на основе которых мне нужно регистрировать или поднимать Exception дальше. Я создал метод декоратора для обработки исключений по типу.
try:
obj.some_method()
except Exception as e:
catch_and_log_exception(e)
def catch_and_log_exception(e):
if isinstance(e, MyConnectionError):
print "Connection error : %s." % e.message
sys.exit(1)
elif isinstance(e, MyConnectionTimeout):
print "Connection to server has been timed out. %s" % e.message
sys.exit(1)
elif isinstance(e, MyException):
message = e.explanation if e.explanation else e.message
log_error_message(str(message))
print "Failed, please check the logs."
sys.exit(1)
else:
raise e
Надеюсь на эту помощь!