Heavily is considered to be hard to read and analyze. It stems from the fact that such code requires more mental effort to understand what it does. The more nested code is, the higher its , which makes it harder to comprehend and test. That’s why deeply nested code is often thought of as an that should be avoided. nested code cyclomatic complexity anti-pattern One of the to reduce nested structuring is using guard clauses, also called . They are chunks of code at the top of the function serving the following purposes: refactoring techniques guard statements for suitability checking passed-in parameters checking the object’s state to decide whether to continue catching unexpected situations before executing the main body In this way, we can reduce the indentation level and make the code’s structure much simpler. Extra nesting level due to the passed-in parameters check We’ll look at the application of in terms of . Let’s look at two examples from the practice where functions’ bodies were placed inside a single if statement. I’ve changed the examples a bit but preserved the main idea. guard clauses checking passed-in parameters def get_characters(file_path: Path) -> List[str]: result = [] if file_path.exists(): with open(file_path, 'r') as file: for line in file: if not is_character_line(line): result.append(line) return result At the top of the function, we check whether the file exists. If it does, we go into the if statement where the function’s main body gets executed. We read the file line by line adding appropriate lines to the result list. At the end of the function, we return the result. We can simplify the function and get rid of the excessive nesting by introducing a guard clause at the top of it. Let’s look at another example where the first line introduces a nesting block for the whole function. @dataclass class AtmMachine: code: str name: str city: str def print_atm_statistics(atms: List[AtmMachine]) -> None: if len(atms) > 0: basic_atm = atms[0] print_atms_in_city(basic_atm.city) process_atms_codes(atms) process_atms_names(atms) print_summary(atms) The code even seems weird-looking because the entire function is placed inside an if statement. The dataclass defines an ATM which has three parameters describing it. The function receives a list of as a parameter to process them somehow. In the case of a valid parameter, the whole processing is executed inside a single conditional. print_atm_statistics atms Placing the entire function inside a single conditional is a frequent pattern encountered in my work. Functions start with if conditional representing parameters checks of some sort. Introducing the Guard Clause We could improve the examples by adding the that would check for unsuitable parameters at the top of the function, . guard clause reducing one redundant nesting level The first example transforms into: def get_characters(file_path: Path) -> List[str]: if not file_path.exists(): return [] result = [] with open(file_path, 'r') as file: for line in file: if not is_character_line(line): result.append(line) return result The introduction of the guard clause has allowed us to remove one indentation level and thus improve the readability. It’s reasonable to immediately return if any of the parameters doesn’t suit for any reason. In this case, if the file doesn’t exist, we instantly return meaning we have nothing to process. As for the second example with ATMs: def print_atm_statistics(atms: List[AtmMachine]) -> None: if not len(atms): return basic_atm = atms[0] print_atms_in_city(basic_atm.city) process_atms_codes(atms) process_atms_names(atms) print_summary(atms) The guard has also helped to remove an extra level of nesting inside the function. We’ve inverted the conditional for the parameters check, moving it to the top of the function. When the list is empty, we return at once because there is nothing to process. Generally, you can use the following . pattern to remove an extra indentation level # before def func(): if guard: # do something # do something # do something # after def func(): if not guard: return # do something # do something # do something Nested code often naturally occurs during development. Most of the time, the first code’s draft is not the best in terms of readability and perception. That’s why after finishing work with a particular piece of code, it makes sense to revise it. is a valuable refactoring technique helping in code improvement by making it much flatter and more readable. Guard clause Occasionally, a function may start with a conditional that checks parameters for suitability. As a result, the entire function may end up inside a single conditional, which makes it artificially complicated. By inverting the condition, we can reduce an additional indentation level making the code clearer.