Я хотел бы реализовать отложенное исключение в Python, которое нормально хранить где-то, но как только оно каким-либо образом используется, оно вызывает исключение, которое было отложено. Что-то вроде этого:реализация отложенного исключения в Python
# this doesn't work but it's a start
class DeferredException(object):
def __init__(self, exc):
self.exc = exc
def __getattr__(self, key):
raise self.exc
# example:
mydict = {'foo': 3}
try:
myval = obtain_some_number()
except Exception as e:
myval = DeferredException(e)
mydict['myval'] = myval
def plus_two(x):
print x+2
# later on...
plus_two(mydict['foo']) # prints 5
we_dont_use_this_val = mydict['myval'] # Always ok to store this value if not used
plus_two(mydict['myval']) # If obtain_some_number() failed earlier,
# re-raises the exception, otherwise prints the value + 2.
Вариант использования заключается в том, что я хочу написать код для анализа некоторых значений из входящих данных; если этот код выходит из строя, но результаты никогда не используются, я хочу, чтобы он терпел неудачу; если он терпит неудачу, но результаты будут использованы позже, то я бы хотел, чтобы не распространялся.
Любые предложения о том, как это сделать? Если я использую мой класс DeferredException я получаю этот результат:
>>> ke = KeyError('something')
>>> de = DeferredException(ke)
>>> de.bang # yay, this works
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __getattr__
KeyError: 'something'
>>> de+2 # boo, this doesn't
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'DeferredException' and 'int'
Я полагаю, ваша функция может вернуть функцию, которая либо генерирует значения, либо вызывает ошибку, но в противном случае я не вижу, как вы могли это сделать. – jonrsharpe
Ну, вы можете перегрузить * все * специальные функции ('__add__',' __call__' и т. Д.) ... Я не уверен, что мне нравится эта идея отложенного исключения, хотя - конечно, это неожиданно для исключений в безобидном коде, удаленном от того, где произошла фактическая ошибка? – Cameron
Почему бы не сохранить состояние/использовать блоки 'finally' вместо того, чтобы пытаться сделать что-то магическое. – wim