📜 Как показано в исходном PDF
Исходный материал демонстрирует вложенные условия на примере проверки прав пользователя:
role = "admin"
section_access = True
if role == "admin":
print("Вы администратор.")
if section_access:
print("У вас есть доступ к разделу.")
else:
print("У вас нет доступа к разделу.")
else:
print("Вы не администратор.")
Что здесь происходит: сначала проверяется роль, и только для администратора проверяется доступ. Логика верная, но уже на двух уровнях вложенности код начинает «уходить вправо».
❌ Почему этот подход может быть не лучшим сейчас
- Глубина вложенности. Каждый новый
ifвнутри другого добавляет отступ. При трёх-четырёх уровнях строки уходят далеко вправо, и код сложно воспринимать. - Смешение ответственности. В одном блоке проверяется и роль, и доступ. Разделить эти проверки помогает быстрее находить ошибки.
- Трудности с расширением. Добавить новую роль или новое условие доступа в глубоко вложенной структуре сложнее, чем в плоской.
✅ Рекомендуемый современный вариант
Тот же сценарий без лишней вложенности. Сначала обрабатываем простые случаи, затем основной:
role = "admin"
section_access = True
if role != "admin":
print("Вы не администратор.")
elif not section_access:
print("Вы администратор.")
print("У вас нет доступа к разделу.")
else:
print("Вы администратор.")
print("У вас есть доступ к разделу.")
Что улучшилось: все проверки находятся на одном уровне отступа. Каждый блок отвечает за свой случай, и логика читается сверху вниз как набор правил.
- Меньше уровней отступов — код не уходит вправо.
- Каждое условие видно сразу, не нужно разворачивать вложенные блоки.
- Проще добавлять новые роли и проверки.
🛡️ Guard clauses (ранний возврат)
В функциях часто применяют приём guard clause: сначала проверяются «плохие» случаи и сразу возвращается результат, а основная логика остаётся на верхнем уровне.
def describe_access(role, section_access):
if role != "admin":
return "Вы не администратор."
if not section_access:
return "У вас нет доступа к разделу."
return "У вас есть доступ к разделу."
print(describe_access("admin", True))
🎯 match-case вместо длинных цепочек elif
Если нужно сравнить одну переменную с множеством значений, современный Python предлагает match-case вместо длинной лестницы elif.
month = 3
match month:
case 12 | 1 | 2:
season = "Зима"
case 3 | 4 | 5:
season = "Весна"
case 6 | 7 | 8:
season = "Лето"
case 9 | 10 | 11:
season = "Осень"
case _:
season = "Некорректный месяц"
print(season)
🕰️ Когда старый подход ещё можно встретить
Вложенные условия всё ещё уместны, когда проверки действительно иерархичны: сначала проверяем существование объекта, затем — его свойство, затем — свойство свойства. Например:
if user is not None:
if user.account is not None:
if user.account.is_active:
print("Активный пользователь")
Даже здесь современный стиль часто заменяет такую вложенность цепочкой and или guard clauses, но в legacy-коде вложенность встречается часто. Главное — уметь её распознавать и постепенно упрощать.