A Pythonic way for “resume next” on exceptions?

2020-02-28 05:54发布

问题:

The problem: I am reading a series of heterogeneous input files. I wrote a reader class for each of them, which reads the file using __init__(self, file_name), and throws an exception in case of malformed input.

The code looks like this:

clients              = Clients             ('Clients.csv'             )
simulation           = Simulation          ('Simulation.csv'          )
indicators           = Indicators          ('Indicators.csv'          )
legalEntity          = LegalEntity         ('LegalEntity.csv'         )
defaultPortfolio     = DefaultPortfolio    ('DefaultPortfolio.csv'    )
excludedProductTypes = ExcludedProductTypes('ExcludedProductTypes.csv')

The problem is that I want not to die at the first malformed file, but instead read all of them and THEN die if at least one was malformed. The only way to do it that I could find looks horrible:

my errors = []    

try:
    clients              = Clients             ('Clients.csv'             )
except Exception, e:
    errors.append(e)
try:
    simulation           = Simulation          ('Simulation.csv'          )
except Exception, e:
    errors.append(e)
try:
    indicators           = Indicators          ('Indicators.csv'          )
except Exception, e:
    errors.append(e)
try:
    legalEntity          = LegalEntity         ('LegalEntity.csv'         )
except Exception, e:
    errors.append(e)
try:
    defaultPortfolio     = DefaultPortfolio    ('DefaultPortfolio.csv'    )
except Exception, e:
    errors.append(e)
try:
    excludedProductTypes = ExcludedProductTypes('ExcludedProductTypes.csv')
except Exception, e:
    errors.append(e)

if len(errors) > 0:
    raise MultipleErrors(errors)

Is there a better looking way to approach the problem?

回答1:

Store the classes and files in a sequence, the results into a dictionary:

inputs = (
    (Clients, 'Clients.csv'),
    (Simulation, 'Simulation.csv'),
    (Indicators, 'Indicators.csv'),
    (LegalEntity, 'LegalEntity.csv'),
    (DefaultPortfolio, 'DefaultPortfolio.csv'),
    (ExcludedProductTypes, 'ExcludedProductTypes.csv'),
)

results = {}
errors = []
for cls, filename in inputs:
    try:
        results[cls.__name__[0].lower() + cls.__name__[1:]] = cls(filename)
    except Exception, e:
        errors.append(e)

if errors:
    raise MultipleErrors(errors)


回答2:

You can try something like this:

handlers_mapping = {
    Clients: 'Clients.csv',
    Simulator: 'Simulator.csv',
    Indicators: 'Indicators.csv',
    LegalEntity: 'LegalEntity.csv',
    DefaultPortfolio: 'DefaultPortfolio.csv',
    ExcludedProductTypes: 'ExcludedProductTypes.csv'
}

results = {}
errors = []
for handler, file_name in handlers_mapping.iteritems():
    try:
        results[handler] = handler(file_name)
    except Exception, e:
        errors.append(e)