Another option would be to pass as arguments to the function just those variables that you are interested in saving in case of something catastrophic.
A decorator that might help you to do this:
import os
try:
import cPickle as pickle
except ImportError:
import pickle
def save_args_if_exception(pickle_folder):
def real_decorator(function):
def wrapper(*args, **kwargs):
try:
function(*args, **kwargs)
except:
print 'FAILING SAFE: Saving arguments to folder:'
print pickle_folder
for arg_position, arg in enumerate(args, start=1):
arg_fname = os.path.join(pickle_folder, str(arg_position) +
'.pickle')
print 'Saving positional argument-{}'.format(arg_position)
with open(arg_fname, mode='wb') as f:
pickle.dump(arg, f)
print 'Saving keyword arguments (kwargs)'
with open(os.path.join(pickle_folder, 'kwargs.pickle'),
mode='wb') as f:
pickle.dump(kwargs, f)
raise # re-raise original exception
return wrapper
return real_decorator
@save_args_if_exception(os.getcwd())
def important_function(first_arg, second_arg=2, **kwargs):
print 'About to raise an exception!'
raise Exception
important_function(3)
Note that in this example, second_arg
is not saved to a file, presumably because of the way Python handles default arguments. Depending on your situation, this may or may not be useful behavior.
References: