How to simplify repetitive try-except blocks

Question:

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

Asked By: LaBeaux

||

Answers:

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).

Answered By: Samwise