Реальный Python
3.64K subscribers
838 photos
10 videos
7 files
888 links
Все о пайтон, новости, подборки на русском и английском. По всем вопросам @evgenycarter
Download Telegram
Вложенные циклы в Python

Вложенные циклы позволяют размещать один цикл внутри другого и тем самым выполнять повторяющиеся действия над несколькими последовательностями. Понимание этой концепции помогает писать более эффективный код, управлять сложными структурами данных и избегать проблем с читабельностью и производительностью.

Начало работы с вложенными циклами

В Python есть два основных типа циклов — for и while.

* for -цикл проходит по элементам последовательности (списка, диапазона и т. д.), когда количество итераций известно заранее.
* while -цикл выполняется, пока истинно заданное условие, и полезен, когда число итераций заранее не определено.

Вложенный цикл создаётся размещением одного цикла внутри другого:


for outer_variable in outer_iterable:
for inner_variable in inner_iterable:
<body>


Для каждой итерации внешнего цикла внутренний выполняется полностью.

Аналогия: часовая и минутная стрелки часов. Часовая проходит круг за 12 часов, минутная — за 1 час, но работают они совместно.


for hour in range(24):
for minute in range(60):
print(f"{hour:02d}:{minute:02d}")


Практические примеры

Печать шаблонов


height = 6
sail_patterns = "*#-x+o"
for row in range(height):
pattern = ""
spacing = " " * (height - row)
for symbol in sail_patterns:
pattern += symbol * row + spacing
print(pattern)


Таблица умножения


for multiplicant in range(1, 11):
for multiplier in range(1, 4):
expression = f"{multiplicant:>2d} × {multiplier}"
product = multiplicant * multiplier
print(f"{expression} = {product:>2d}", end="\t")
print()


Суммирование элементов во вложенных списках


resource_donators = [
[8, 6, 3],
[9, 2, 7],
[4, 1, 5]
]
total_resources = 0
for planet in resource_donators:
for resource in planet:
total_resources += resource
print(total_resources) # 45


Парные комбинации без самих себя


players = ["Bonnie", "Mike", "Raj", "Adah"]
for player1 in players:
for player2 in players:
if player1 != player2:
print(f"{player1} vs {player2}")


Вложенный while


while True:
word = input("Введите слово (exit — для выхода): ")
if word == "exit":
break
for letter in word:
print(letter)


Частые проблемы вложенных циклов

* Область видимости переменных. Не используйте одинаковые имена во внешнем и внутреннем циклах.
* Читаемость. Глубокая вложенность усложняет понимание кода.
* Производительность. Каждый дополнительный уровень увеличивает временную сложность (часто до O(n²) и выше).

Оптимизация

* break и continue позволяют досрочно завершать цикл или пропускать ненужные итерации.
* List Comprehension делает выражения компактнее, хотя не всегда улучшает производительность.


# Поиск "bacon" с break
for layer in blt_sandwich:
for ingredient in layer:
if ingredient == target:
print("Found bacon!")
break
if target in layer:
break


Вывод

Вложенные циклы — мощный инструмент для работы с многомерными данными и повторяющимися задачами. Однако злоупотребление ими ухудшает читаемость и скорость. Используйте их осознанно, оптимизируйте при помощи break, continue и list comprehension, и никогда не забывайте о сложности алгоритма.

https://realpython.com/nested-loops-python/

#python

👉 @python_real
👍2❤1
🐍 Как работают интерфейсы в Python и зачем они нужны?

В Python нет специального ключевого слова interface (как, например, в Java или C#), но это не значит, что мы не можем создавать надежные контракты для наших классов!

Свежая и очень подробная статья от *Real Python* разбирает, как правильно реализовывать интерфейсы в Python. Вот два основных механизма:

🔹 Абстрактные базовые классы (ABCs)
Используем модуль abc и декоратор @abstractmethod. Это строгий подход на основе наследования: если ваш дочерний класс не реализует все необходимые методы, Python выдаст ошибку TypeError еще на этапе создания объекта (instantiation), а не тогда, когда код упадет во время выполнения.

🔹 Протоколы (Protocols)
Современный подход структурной типизации с помощью typing.Protocol. Вашим классам вообще не нужно наследовать протокол — достаточно просто иметь нужные методы с правильными сигнатурами. Это идеально подходит для проверки статическими анализаторами кода (например, `mypy`).

🦆 Duck Typing (Утиная типизация)
Куда же без нее! Python по своей природе динамичен: "если объект ходит как утка и крякает как утка, то это утка". ABC и Протоколы просто берут эту концепцию и делают ее безопаснее, позволяя использовать isinstance() и issubclass() для проверки контрактов.

Понимание интерфейсов помогает применять принципы объектно-ориентированного дизайна (SOLID) и писать код, который работает с различными типами данных без жесткой привязки к их конкретным реализациям.

https://realpython.com/python-interface/

#python

👉 @python_real
👍1
UV

Чрезвычайно быстрый менеджер пакетов и проектов на языке Python, написанный на Rust.

Создатели позиционируют его как замену pip, pip-tools и virtualenv. Это, кстати, те же разработчики, которые сделали линтер Ruff.

https://astral.sh/blog/uv

https://github.com/astral-sh/uv

#python

👉 @python_real
👍2😁2
Реализация парсеров с Pylasu

В этой статье рассказывается, как реализовать парсеры на Python с использованием Pylasu и ANTLR. Пошагово:

1. Создадим грамматику ANTLR для простого языка программирования Slang и сгенерируем парсер.
2. Определим абстрактное синтаксическое дерево (AST) с помощью Pylasu и научимся строить его из дерева разбора ANTLR.
3. Интегрируем парсер с CLI-приложением для обработки кода Slang из строк и файлов, с выводом AST в формате JSON.

Полный код проекта доступен на GitHub. Вы можете экспериментировать, вносить улучшения и делиться идеями!

https://tomassetti.me/implement-parsers-with-pylasu/

#python

👉 @python_real
👍2
Начиная с Python 3.0, при возникновении нового исключения внутри блока except перехваченное исключение автоматически сохраняется в атрибуте __context__ создаваемого исключения. В результате при выводе будут показаны оба исключения:


try:
1 / 0
except ZeroDivisionError:
raise ValueError('Zero!')



(most recent call last):
File "test.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "test.py", line 4, in <module>
raise ValueError('Zero!')
ValueError: Zero!


Кроме того, вы можете явно указать причинное исключение, использовав конструкцию raise … from. Тогда в атрибут __cause__ нового исключения будет помещено исходное:


division_error = None

try:
1 / 0
except ZeroDivisionError as e:
division_error = e

raise ValueError('Zero!') from division_error



(most recent call last):
File "test.py", line 4, in <module>
1 / 0
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "test.py", line 8, in <module>
raise ValueError('Zero!') from division_error
ValueError: Zero!


#python

👉 @python_real
👍1
Метод format в Python для строк — мощный инструмент, поддерживающий множество возможностей, о которых вы, возможно, даже не знали. Каждый заменяемый плейсхолдер ({...}) может содержать три части: имя поля, преобразование и спецификацию формата.

Имя поля используется для указания, какой именно аргумент должен быть подставлен:


>>> '{}'.format(42)
'42'
>>> '{1}'.format(1, 2)
'2'
>>> '{y}'.format(x=1, y=2)
'2'


Преобразование позволяет указать, что вместо str() следует использовать repr() (или ascii()) при преобразовании объектов в строки:


>>> '{!r}'.format(datetime.now())
'datetime.datetime(2018, 5, 3, 23, 48, 49, 157037)'
>>> '{}'.format(datetime.now())
'2018-05-03 23:49:01.060852'


Спецификация формата задаёт, как значения будут представлены:


>>> '{:+,}'.format(1234567)
'+1,234,567'
>>> '{:>19}'.format(1234567)
' 1234567'


Эта спецификация может быть применена и к отдельному объекту с помощью функции format (не метода str):


>>> format(5000000, '+,')
'+5,000,000'


Функция format вызывает метод __format__ объекта, поэтому вы можете изменить его поведение для своих типов.

#python

👉 @python_real
❤1👍1
🐍 Интерфейсы в Python: когда ABC уже недостаточно?

В Python нет привычных интерфейсов, как в Java или C#, но это не значит, что их нельзя использовать. На практике разработчики применяют несколько подходов — от обычного duck typing до абстрактных базовых классов (abc) и современных Protocol из модуля typing.

Что важно знать:

🔹 Duck typing — классический подход Python. Если объект реализует нужные методы, значит, он подходит, независимо от наследования.

🔹 ABC (Abstract Base Classes) — позволяют явно определить набор обязательных методов. Если наследник не реализует их, создать экземпляр класса не получится.

🔹 Protocol — современный способ описывать интерфейсы без наследования. Особенно полезен при использовании статической проверки типов (mypy, Pyright и др.). Код становится гибче, а зависимости между классами — слабее.

💡 Когда что использовать?

* Небольшие проекты — достаточно duck typing.
* Средние и крупные проекты — ABC помогает избежать ошибок реализации.
* Современные кодовые базы с type hints — чаще всего лучший выбор Protocol, который не требует наследования и отлично сочетается с IDE и статическими анализаторами.

Если вы до сих пор считаете, что интерфейсов в Python нет, возможно, вы просто ещё не познакомились с Protocol.

https://realpython.com/python-interface/

#python

👉 @python_real
👍1
🐍 Как использовать Claude Code для разработки и отладки проектов на Python

Real Python опубликовал подробное руководство по работе с Claude Code — консольным ИИ-инструментом, который запускается непосредственно в каталоге проекта.

В отличие от браузерных чат-ботов, Claude Code может:

🔹 изучать структуру проекта и содержимое файлов;
🔹 создавать и редактировать код;
🔹 показывать изменения в формате diff;
🔹 запускать команды и тесты;
🔹 искать и исправлять ошибки;
🔹 работать с Git и создавать коммиты.

В руководстве предлагается с нуля разработать на Python консольный менеджер контактов. Сначала Claude Code составляет план и структуру приложения, затем генерирует код, проверяет его работу и пишет тесты. После этого инструмент используют для анализа уже существующего проекта и исправления найденных проблем.

Отдельное внимание уделено безопасному рабочему процессу:

✅ запускать Claude Code только внутри каталога проекта;
✅ начинать сложные задачи в режиме Plan;
✅ хранить требования к проекту в файле CLAUDE.md;
✅ проверять каждый diff перед применением;
✅ запускать тесты после изменений;
✅ регулярно создавать коммиты, чтобы иметь возможность отката.

Для работы потребуется платная подписка Claude либо учётная запись Anthropic Console с подключённой оплатой API.

https://realpython.com/how-to-use-claude-code/

#python

👉 @python_real
👍2
🐍 Асинхронное программирование в Python: от генераторов до asyncio

Почему обычная программа простаивает во время сетевых запросов, обращения к базе данных или чтения файлов? И как заставить её выполнять другие задачи, пока она ждёт ответа?

В новом подробном руководстве Real Python асинхронность разбирают постепенно — от синхронного кода и генераторов с yield до полноценной работы с asyncio.

Из материала вы узнаете:

🔹 чем синхронное выполнение отличается от асинхронного;
🔹 что такое блокирующие и неблокирующие операции;
🔹 как устроен цикл событий;
🔹 как работают async, await и корутины;
🔹 как запускать несколько задач через asyncio.TaskGroup;
🔹 почему асинхронность особенно полезна для HTTP-запросов, баз данных и другого I/O;
🔹 как отслеживать состояние выполняющихся задач.

Авторы не просто показывают готовый код, а последовательно создают собственную модель кооперативной многозадачности на генераторах. Благодаря этому становится понятнее, что именно скрывается за работой asyncio.

Примеры рассчитаны на Python 3.11 и новее. К статье прилагаются исходники и интерактивный тест.

https://realpython.com/python-async-features/

#python

👉 @python_real
👍1🔥1
🐍 В Python 3.15 появится frozendict - словарь, который нельзя изменить

Это встроенный тип для случаев, когда данные должны оставаться неизменными после создания: например, для настроек или результатов вычислений.


settings = frozendict(theme="dark", language="ru")
print(settings["theme"]) # dark

settings["theme"] = "light" # TypeError


Если ключи и значения поддерживают хеширование, frozendict можно использовать как ключ другого словаря или элемент множества. Но есть нюанс: неизменяемость не распространяется на вложенные объекты. Если внутри лежит список, его содержимое всё ещё можно менять.

Функция уже описана в PEP 814 https://peps.python.org/pep-0814/) и включена в предварительные версии Python 3.15.

Подробнее в статье https://realpython.com/python315-frozendict/

#python

👉 @python_real
👍2
📊 Статистика в Python: с чего начать анализ данных

Среднее значение может скрыть важную деталь. Возьмём числа 1, 2, 3, 4, 100: среднее равно 22, а медиана — 3. Одно большое значение сильно изменило картину.

В подробном руководстве Real Python разбирают, как описывать данные с помощью Python:

• находить среднее, медиану и моду;
• измерять разброс значений и изучать корреляцию;
• работать с выбросами и пропущенными значениями;
• строить гистограммы, диаграммы и другие графики.

Для небольших задач хватит встроенного модуля statistics. Для массивов, таблиц и визуализации пригодятся NumPy, pandas, SciPy и Matplotlib.

Пример для быстрого старта:


from statistics import mean, median

data = [1, 2, 3, 4, 100]

print(mean(data)) # 22
print(median(data)) # 3


https://realpython.com/python-statistics/

#python

👉 @python_real
👍1