Python — язык, который удивляет своей гибкостью и глубиной даже тех, кто пишет на нём годами. За кажущейся простотой скрываются мощные инструменты, способные сделать ваш код лаконичнее, эффективнее и элегантнее. Эта шпаргалка собрала ключевые приёмы, о которых многие забывают или не догадываются, разделив их по уровням мастерства: от базовых «фишек» до экспертных техник.
Вы узнаете, как распаковывать коллекции одной строчкой, зачем циклу `else`, как декораторы с параметрами ускоряют код и почему `__slots__` экономит память. Мы заглянем в метаклассы, модификацию байткода и асинхронные паттерны, а также разберём полезные модули вроде `itertools` и трюки с аннотациями типов.
Здесь нет очевидных вещей вроде списковых включений — только те приёмы, которые редко встречаются в туториалах, но способны преобразить ваш подход к коду. Готовы перейти на новый уровень? Сохраните эту шпаргалку, экспериментируйте и делитесь находками — Python всегда готов удивить вас снова.
Базовые фичи, о которых многие не знают
Распаковка коллекций
Оператор * позволяет элегантно распаковывать части списков или кортежей:
# a = 1, b = [2, 3, 4], c = 5
Это удобно для работы с многомерными структурами данных, например, при распаковке вложенных списков.
Множественное присваивание
Можно обменивать значения переменных без временных переменных:
Также возможно комбинировать присваивание с условиями в одну строку, что делает код компактнее.
F-строки с выражениями и форматированием
F-строки (с Python 3.6) поддерживают выражения внутри себя:
Вы можете форматировать числа, даты или вызывать методы объектов прямо в f-строках, что упрощает создание читаемого вывода.
else в циклах и try-except
Блок else в циклах for и while выполняется, если цикл завершился без прерывания через break:
if i > 10:
break
else:
print("Цикл завершился естественно")
В try-except блок else выполняется, если исключений не возникло, разделяя основной код от обработки ошибок.
Продвинутые приемы
Декораторы с параметрами
Декораторы могут принимать аргументы для настройки их поведения. Пример с кэшированием:
@lru_cache(maxsize=100)
def expensive_function(x):
return x * x # Результат кэшируется
Это ускоряет выполнение за счёт сохранения результатов предыдущих вызовов.
Контекстные менеджеры без with
Вы можете управлять контекстными менеджерами вручную через методы __enter__ и __exit__. А с модулем contextlib можно создавать их из генераторов:
@contextmanager
def my_context():
print("Вход")
yield
print("Выход")
with my_context():
print("Работа внутри")
Оптимизация памяти через __slots__
Использование __slots__ заменяет словарь атрибутов на фиксированный набор, экономя память:
__slots__ = ['attr1', 'attr2']
def __init__(self):
self.attr1 = 1
self.attr2 = 2
Это полезно при создании множества экземпляров.
Генераторы и yield from
Конструкция yield from упрощает работу с вложенными генераторами:
yield from range(10)
def main_generator():
yield from subgenerator()
Код становится чище и понятнее.
Экспертные техники
Метаклассы и динамическое создание классов
Функция type позволяет создавать классы динамически:
Это полезно для автоматической регистрации подклассов или добавления методов.
Интроспекция кода с inspect
Модуль inspect помогает анализировать код:
def my_function():
pass
print(inspect.getsource(my_function)) # Выводит исходный код
Отлично подходит для отладки и создания инструментов анализа.
Модификация байткода
С библиотеками dis и byteplay можно анализировать и изменять байткод для оптимизации или создания профилировщиков:
def func():
return 1 + 2
dis.dis(func) # Показывает байткод
Асинхронные трюки
Асинхронные конструкции вроде async for и async with можно использовать в своих объектах. А asyncio.run_in_executor помогает интегрировать синхронный код:
async def async_task():
await asyncio.sleep(1)
print("Готово")
Полезные модули и инструменты
itertools и functools
itertools.chain объединяет итераторы:
result = list(chain([1, 2], [3, 4])) # [1, 2, 3, 4]
functools.partial создаёт функции с частично заданными аргументами.
Аннотации типов не для проверки
Аннотации доступны в runtime через __annotations__:
return str(x)
print(func.__annotations__) # {'x': int, 'return': str}
Полезно для валидации данных.
Оператор := (морж)
Оператор := (с Python 3.8) присваивает значение внутри выражений:
print(f"Длина: {n}") # Длина: 3
Упрощает код и повышает читаемость.
Python полон скрытых возможностей, которые могут удивить даже опытных разработчиков. Экспериментируйте с этими техниками, изучайте документацию и делитесь своими находками в комментариях — возможно, вы откроете что-то новое для других!