Search code examples
pythonerror-handlinglookuptry-except

How to simplify repetitive try-except blocks


I have the below code that needs to check if the visible property of any of the objects are found. Each of the acronym functions in the try-except blocks return an object reference if found, each with their own visible property. If any of the acronym objects are not found my program will throw a LookUpError as a result of calling (e.g.) DR(). I feel like there has to be a way to simplify this code such that I don't have to specify all these separate try-except blocks, but I cannot think about how to effectively to that.

    def detect_planning_workflow_page():
        
        workflow = None
        
        try:
            if DR().visible:
                workflow = "DR"
        except LookupError:
            pass
        
        try:
            if LL().visible:
                workflow = "LL"
        except LookupError:
            pass
        
        try:
            if AZ().visible:
                workflow = "AZ"
        except LookupError:
            pass
        
        try:
            if SP().visible:
                workflow = "SP"
        except LookupError:
            pass
        
        try:
            if MS().visible:
                workflow = "Define Region"
        except LookupError:
            pass
        
        return workflow


Solution

  • I'd write this using a loop:

        def detect_planning_workflow_page():
            for func, workflow in [
                (MS, "Define Region"),
                (SP, "SP"),
                (AZ, "AZ"),
                (LL, "LL"),
                (DR, "DR"),
            ]:
                try:
                    if func().visible:
                        return workflow
                except LookupError:
                    pass
            return None
    

    Note that I reversed the order from your original code because your original code will keep overwriting workflow if multiple checks succeed, therefore the last one will take precedence -- swapping the order and returning immediately should have the same effect (unless calling func() on the others has an important side effect that's not obvious from your description).