The **"Single Level of Abstraction" principle** states, as the name suggests, that a function should be written in a single level of abstraction throughout its whole scope. In case there are several levels of abstraction involved, different parts of the code should be extracted to their own functions to ensure the principle.
For example, the following Python code:
```python
from pathlib import Path
def count_module_comments(path: Path) -> int:
result = 0
for filename in path.glob("**/*.py"):
with open(filename, "r") as f:
for line in f.readlines():
if line.lstrip().startswith("#"):
result += 1
return result
```
We can see that the code is quite compact, but there are several functions that are working at different levels of abstraction. It is not a problem in a code this size, but modifications could prove to be hard and the code can be hard to iterate on.
Trying to isolate the abstraction levels results in a code with more vertical space but arguably easier to read:
```python
from pathlib import Path
from collections.abc import Iterable
def python_files(path: Path) -> Iterable[Path]:
return path.glob("**/*.py")
def is_comment(line: str) -> bool:
return line.lstrip().startswith("#")
def count_file_comments(filename: Path) -> int:
with open(filename, "r") as f:
return sum(1 for line in f.readlines() if is_comment(line))
def count_module_comments(path: Path) -> int:
return sum(count_file_comments(f) for f in python_files(path))
```
Even if it may look harder to grasp at the moment, this code is better isolated and making changes (for example, including different definitions of comments or translating it to a different language) should be much easier.