0

I'm writing a script where I need to try to apply several parsing method on an email. So if the first one succeeded there's no need to try the other ones. Until now I have only 2 parsing method but it's possible that I'll add many more. If possible I would like to replicate something like a switch case (that don't exist in 2.7). Is there a better than what I'm doing?

try:
    found['PhishMe_Informations']=self.parse_phishme(message)

except MalformedPhishMeMailError as e:
    self.log.error(e[0])
    found['PhishMe_Informations']=e[1]
    found['PhishMe_Informations']['Malformed']=True

except Exception:
    try:
        found['Journaling_Informations']=self.parse_journaling(message)

    except MalformedRecordMessageError as e:
         self.log.error(e)

    except Exception:
        pass
martineau
  • 119,623
  • 25
  • 170
  • 301
Yberamos
  • 33
  • 2
  • 3
    There is no switch in python, we have to use `try` - `except`, `try` - `except`, `try` - `except` etc. It can be done using a dictionary and a bit of implementation.. but not very pythonic – Nordle Feb 25 '19 at 12:58
  • the only way to skip the following tries is to have some sort of record that a previous one succeeded (like a boolean)? – Yberamos Feb 25 '19 at 13:03
  • Apart from the use of try/except this is a dupe of: https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python However this recipe might also be useful: http://code.activestate.com/recipes/410695-exception-based-switch-case/ – Simon Hibbs Feb 25 '19 at 13:05
  • what do you mean by "skip the following tries"? The following `try` blocks only execute if the previous `try` fails and enters into the `exception` block (as per the logic of your script) – Nordle Feb 25 '19 at 13:08
  • @Matt B. In this case yes. But if I need to try 20 different parsing method the nested tries would go out of hand. So I'm looking for a way to not have them nested. I'll try to the recipe from Simon Hibbs – Yberamos Feb 25 '19 at 13:14

1 Answers1

0

You could try to build a hierarchic tree of functions and possible exception in declarative mode and then write the code that handles it. In your use case, it could be:

{ cls.parse_phishme: OrderedDict(
        (MalformedPhishMeMailError, cls.process_malformed),
        (Exception, { cls.parse_journaling: OrderedDict(
                (MalformedRecordMessageError, cls.log_err),
                (Exception, None)
            )
    )
}

The method to process that tree could be:

def process_exc_tree(self, d, message):
    if isinstance(d, dict):   # is d a (possibly ordered) dict?
        for func, exc in d.items():
            try:
                self.func(message)    # call the function passed as key
            except Exception as e:              # process the exceptions
                for ex, suite in exc.items():   #  passed as ordered dict
                    if isinstance(e, ex):
                        # Ok found the relevant exception: recurse
                        self.process_exc_tree(suite, message)
    elif d is None:           # if d is None, do nothing
        pass
    else:                     # it should be a function: call it
        self.d(message)
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • I've tried to implement your solution but I've hit a wall. I've managed to make it work correctly but when it catch an MalformedPhishMeMailError exception, it use correctly process_malformed but doesn't stop there. It continues with the other tries... – Yberamos Feb 25 '19 at 17:36