Генераторы — один из самых полезных механизмов в Python. Они имеют множество применений, одно из которых — создание менеджеров контекста. Обычно нужно вручную определять магические методы
Теперь
Кроме того,
Мы в MAX
👉@BookPython
__enter__ и __exit__, но декоратор @contextmanager из модуля contextlib делает это намного удобнее:
from contextlib import contextmanager
@contextmanager
def atomic():
print('BEGIN')
try:
yield
except Exception:
print('ROLLBACK')
else:
print('COMMIT')
Теперь
atomic — это менеджер контекста, который можно использовать следующим образом:
In : with atomic():
...: print('ERROR')
...: raise RuntimeError()
...:
BEGIN
ERROR
ROLLBACK
Кроме того,
@contextmanager позволяет использовать его как декоратор, так и менеджер контекста.
In : @atomic()
...: def ok():
...: print('OK')
...:
In : ok()
...:
BEGIN
OK
COMMIT
Мы в MAX
👉@BookPython
👍2❤🔥1🤡1
Вредные советы python разработчику
В Python можно выпрямить вложенные списки с помощью... функции
Дело в том, что
Мы в MAX
👉@BookPython
l=[['a', 'b', 'c'], ['1', '2'], ['#']]
sum(l, [])
В Python можно выпрямить вложенные списки с помощью... функции
sum(). Вот код (выполнять, пока никто не видит):Дело в том, что
sum() принимает первым аргументом итерируемый объект, а вторым — значение, с которого начинается операция. По умолчанию это 0, но если указать пустой список [], то sum() начнёт с него. Затем sum() последовательно применяет операцию сложения к элементам первого аргумента, начиная со значения второго аргумента. В случае списков это означает конкатенацию.Мы в MAX
👉@BookPython
👍6
В Python вы можете переопределить оператор квадратных скобок ([]), определив магический метод getitem. Примером может быть объект Cycle, который виртуально содержит бесконечное количество повторяющихся элементов:
Необычность здесь заключается в том, что оператор [] поддерживает уникальный синтаксис. Он может использоваться не только так — [2], но и так — [2:10], или [2:10:2], или [2::2], или даже [:]. Семантика — [start:stop:step], но вы можете применять её так, как вам нужно, для ваших собственных объектов.
Но что же получает getitem в качестве параметра index, если использовать этот синтаксис? Для этого существуют объекты slice.
Вы даже можете комбинировать синтаксис кортежей и срезов:
Slice не делает ничего, кроме как просто хранит атрибуты start, stop и step.
Мы в MAX
👉@BookPython
class Cycle:
def __init__(self, lst):
self._lst = lst
def __getitem__(self, index):
return self._lst[index % len(self._lst)]
print(Cycle(['a', 'b', 'c'])[100]) # prints 'b'
Необычность здесь заключается в том, что оператор [] поддерживает уникальный синтаксис. Он может использоваться не только так — [2], но и так — [2:10], или [2:10:2], или [2::2], или даже [:]. Семантика — [start:stop:step], но вы можете применять её так, как вам нужно, для ваших собственных объектов.
Но что же получает getitem в качестве параметра index, если использовать этот синтаксис? Для этого существуют объекты slice.
In : class Inspector:
...: def __getitem__(self, index):
...: print(index)
...:
In : Inspector()[1]
1
In : Inspector()[1:2]
slice(1, 2, None)
In : Inspector()[1:2:3]
slice(1, 2, 3)
In : Inspector()[:]
slice(None, None, None)
Вы даже можете комбинировать синтаксис кортежей и срезов:
In : Inspector()[:, 0, :]
(slice(None, None, None), 0, slice(None, None, None))
Slice не делает ничего, кроме как просто хранит атрибуты start, stop и step.
In : s = slice(1, 2, 3)
In : s.start
Out: 1
In : s.stop
Out: 2
In : s.step
Out: 3
Мы в MAX
👉@BookPython
🔥4❤1
Т-Технологии зовут на Стековку
1 ноября в Екатеринбурге, Новосибирске и Нижнем Новгороде стартует квест для ИТ-специалистов — с городским интерактивом, задачами на знание кода и смекалку.
Что нужно делать?
Решать онлайн- и офлайн-задания и получать за это баллы для своего города.
Какой приз?
В городе, который наберет больше всего баллов, устроят вечеринку. А самые активные участники смогут повлиять на выбор тематики и программы.
Как участвовать?
Просто зарегистрируйтесь до 31 октября
1 ноября в Екатеринбурге, Новосибирске и Нижнем Новгороде стартует квест для ИТ-специалистов — с городским интерактивом, задачами на знание кода и смекалку.
Что нужно делать?
Решать онлайн- и офлайн-задания и получать за это баллы для своего города.
Какой приз?
В городе, который наберет больше всего баллов, устроят вечеринку. А самые активные участники смогут повлиять на выбор тематики и программы.
Как участвовать?
Просто зарегистрируйтесь до 31 октября
❤1
Что такое контекстный менеджер в Python?
Контекстный менеджер в Python — это специальный тип объекта, который определяет методы
Частый сценарий — это работа с файлом:
Здесь контекстный менеджер гарантирует, что файл будет корректно закрыт после завершения блока with, даже если при чтении файла возникнет исключение.
Вот как можно написать простой контекстный менеджер самостоятельно:
Мы в MAX
👉@BookPython
Контекстный менеджер в Python — это специальный тип объекта, который определяет методы
enter() и exit() и используется с инструкцией with. Эти объекты часто применяются в операциях, которые требуют установки и освобождения ресурсов. Частый сценарий — это работа с файлом:
with open('file.txt', 'r') as file:
data = file.read()
Здесь контекстный менеджер гарантирует, что файл будет корректно закрыт после завершения блока with, даже если при чтении файла возникнет исключение.
Вот как можно написать простой контекстный менеджер самостоятельно:
import time
class Timer:
def __enter__(self):
self.start = time.time()
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f'Время выполнения: {self.end - self.start:.2f} секунд')
with Timer():
# код, время выполнения которого нужно измерить
time.sleep(2)
Мы в MAX
👉@BookPython
👍3
Модуль functools для манипуляций с функциями
Модуль
1. `functools.partial`: Позволяет зафиксировать некоторые аргументы функции и создать новую функцию с предопределенными значениями.
2.`functools.partial`: Применяет функцию к паре элементов в последовательности, сокращая ее до одного значения. Обычно используется для аккумуляции значений.
3.
4.
5.
Эти функции и декораторы делают
Мы в MAX
👉@BookPython
Модуль
functools в Python предоставляет инструменты для работы с функциями, позволяя выполнять различные манипуляции с ними. Вот некоторые из наиболее важных функций и возможностей, которые предоставляет functools:1. `functools.partial`: Позволяет зафиксировать некоторые аргументы функции и создать новую функцию с предопределенными значениями.
from functools import partial
def multiply(x, y):
return x * y
double = partial(multiply, 2)
print(double(5)) # Вывод: 10
2.`functools.partial`: Применяет функцию к паре элементов в последовательности, сокращая ее до одного значения. Обычно используется для аккумуляции значений.
from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)
print(product) # Вывод: 24
3.
functools.lru_cache: Кэширует результаты вызовов функции, чтобы ускорить повторные вызовы с теми же аргументами. Полезно для функций с дорогими вычислениями.
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10)) # Вывод: 55
4.
functools.wraps: Декоратор, который сохраняет метаданные оригинальной функции (такие как имя и документация) при создании декоратора.
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Что-то делаем перед вызовом функции")
return func(*args, **kwargs)
return wrapper
@my_decorator
def say_hello():
"""Выводит приветствие."""
print("Привет!")
print(say_hello.__name__) # Вывод: say_hello
print(say_hello.__doc__) # Вывод: Выводит приветствие.
5.
functools.total_ordering: Упрощает реализацию всех методов сравнения для класса, определяя только несколько из них.
from functools import total_ordering
@total_ordering
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
def __lt__(self, other):
return (self.x, self.y) < (other.x, other.y)
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 < p2) # Вывод: True
print(p1 <= p2) # Вывод: True
Эти функции и декораторы делают
functools мощным инструментом для функционального программирования в Python.Мы в MAX
👉@BookPython
👍1
Last Call: ИИ, бэкенд и фронтенд в одном хакатоне
Wink AI Challenge — соревнование для разработчиков, которые знакомы с нейросетями и мультимодальными данными. Разбираешься в NLP и интеграции моделей? Приходи и покажи, на что способен твой ИИ. Призовой фонд — 1 125 000 рублей.
Последние дни регистрации — открыта до 4 ноября включительно: https://cnrlink.com/winkaichallengepylib
ML-инженеры, backend- и frontend-разработчики, DevOps, MLOps и мультимедиа-инженеры — ваш выход. Алгоритм такой:
1️⃣ Получи реальный текстовый набор данных.
2️⃣ Проанализируй структуру и извлеки ключевые сущности.
3️⃣ Собери ИИ-сервис, который помогает принимать решения в киноиндустрии.
Задачи хакатона:
🔸 Построй модель зависимости между сценами и структурируй сценарий.
🔸 Преврати текст в эскизы с помощью text-to-image для создания превизуализации сценария.
🔸 Создай решение, которое классифицирует контент и находит сцены, влияющие на возрастной рейтинг.
Финал пройдёт в Москве — двум участникам из команды Wink оплатит билеты и проживание. Успей зарегистрироваться на первый в России хакатон по применению ИИ в кинопроизводстве: https://cnrlink.com/winkaichallengepylib
Wink AI Challenge — соревнование для разработчиков, которые знакомы с нейросетями и мультимодальными данными. Разбираешься в NLP и интеграции моделей? Приходи и покажи, на что способен твой ИИ. Призовой фонд — 1 125 000 рублей.
Последние дни регистрации — открыта до 4 ноября включительно: https://cnrlink.com/winkaichallengepylib
ML-инженеры, backend- и frontend-разработчики, DevOps, MLOps и мультимедиа-инженеры — ваш выход. Алгоритм такой:
1️⃣ Получи реальный текстовый набор данных.
2️⃣ Проанализируй структуру и извлеки ключевые сущности.
3️⃣ Собери ИИ-сервис, который помогает принимать решения в киноиндустрии.
Задачи хакатона:
🔸 Построй модель зависимости между сценами и структурируй сценарий.
🔸 Преврати текст в эскизы с помощью text-to-image для создания превизуализации сценария.
🔸 Создай решение, которое классифицирует контент и находит сцены, влияющие на возрастной рейтинг.
Финал пройдёт в Москве — двум участникам из команды Wink оплатит билеты и проживание. Успей зарегистрироваться на первый в России хакатон по применению ИИ в кинопроизводстве: https://cnrlink.com/winkaichallengepylib
Гринатом — ИТ-интегратор Росатома — ищет системного архитектора АРМ в Москве!💼
✅Вам предстоит разрабатывать архитектурные концепции и технические решения на АРМ, готовить презентации и обоснования архитектурных решений, проводить аудит и анализ текущей инфраструктуры, разрабатывать стратегии миграции на отечественные платформы и участвовать в разработке проектной документации.
🤝А мы предложим конкурентоспособную «белую» зарплату с годовыми бонусами и ежегодной индексацией, ДМС со стоматологией, тренажерный зал с сауной в офисе, образовательные курсы за счёт компании. И главное — карьерный и экспертный рост в рамках единой команды.
✅Вам предстоит разрабатывать архитектурные концепции и технические решения на АРМ, готовить презентации и обоснования архитектурных решений, проводить аудит и анализ текущей инфраструктуры, разрабатывать стратегии миграции на отечественные платформы и участвовать в разработке проектной документации.
🤝А мы предложим конкурентоспособную «белую» зарплату с годовыми бонусами и ежегодной индексацией, ДМС со стоматологией, тренажерный зал с сауной в офисе, образовательные курсы за счёт компании. И главное — карьерный и экспертный рост в рамках единой команды.
hh.ru
Вакансия Системный архитектор АРМ в Москве, работа в компании Гринатом. Бэк-офис
Зарплата: не указана. Москва. Требуемый опыт: 3–6 лет. Полная. Дата публикации: 02.11.2025.
🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
BBOT (Black Box OSINT Toolkit)
Рекурсивный модульный OSINT инструмент, написанный на Python.
Он поддерживает модульную структуру, интеграцию с API и плагины для выполнения сетевых сканирований, анализа доменов, поиска утечек данных и других задач. BBOT нацелен на исследование целевых систем, обеспечивая гибкость и настраиваемость для профессионалов в области кибербезопасности.
https://github.com/blacklanternsecurity/bbot
Мы в MAX
👉@BookPython
Рекурсивный модульный OSINT инструмент, написанный на Python.
Он поддерживает модульную структуру, интеграцию с API и плагины для выполнения сетевых сканирований, анализа доменов, поиска утечек данных и других задач. BBOT нацелен на исследование целевых систем, обеспечивая гибкость и настраиваемость для профессионалов в области кибербезопасности.
https://github.com/blacklanternsecurity/bbot
Мы в MAX
👉@BookPython
👍1
Если вы хотите игнорировать какое-то исключение, вы, вероятно, сделаете что-то вроде этого:
Это будет работать (ничего не выводя), но
📲 Мы в MAX
👉@BookPython
try:
lst = [1, 2, 3, 4, 5]
print(lst[10])
except IndexError:
pass
Это будет работать (ничего не выводя), но
contextlib позволяет сделать то же самое более выразительно и семантически правильно:
from contextlib import suppress
with suppress(IndexError):
lst = [1, 2, 3, 4, 5]
lst[10]
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Media is too big
VIEW IN TELEGRAM
Как использовать *args и **kwargs в python?
В видео про декораторы мы использовали
📲 Мы в MAX
👉@BookPython
В видео про декораторы мы использовали
*args и **kwargs для того, чтобы передать в функцию любое количество позиционных и именованных аргументов. Для того, чтобы понять как это работает, сначала познакомимся с тем, что такое распаковка.👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊2
Распаковка параметров функций в Python 2 и 3
В Python 2 существовала интересная возможность распаковывать параметры функций прямо в их определении. Пример:
Более того, это работало даже рекурсивно:
Но начиная с Python 3, эта возможность была удалена из языка. Чтобы добиться того же результата, теперь нужно распаковывать параметры вручную:
Удаление этой функциональности сделало код более явным и читаемым, но для любителей компактности Python 2 по-прежнему вызывает лёгкую ностальгию.
📲 Мы в MAX
👉@BookPython
В Python 2 существовала интересная возможность распаковывать параметры функций прямо в их определении. Пример:
def between(x, (start, stop)):
return start < x < stop
interval = (5, 10)
print(between(2, interval)) # False
print(between(7, interval)) # True
Более того, это работало даже рекурсивно:
def determinant_2_x_2(((a, b), (c, d))):
return a * d - c * b
matrix = [
(1, 2),
(3, 4),
]
print(determinant_2_x_2(matrix)) # -2
Но начиная с Python 3, эта возможность была удалена из языка. Чтобы добиться того же результата, теперь нужно распаковывать параметры вручную:
def determinant_2_x_2(matrix):
row1, row2 = matrix
a, b = row1
c, d = row2
return a * d - c * b
matrix = [
(1, 2),
(3, 4),
]
print(determinant_2_x_2(matrix)) # -2
Удаление этой функциональности сделало код более явным и читаемым, но для любителей компактности Python 2 по-прежнему вызывает лёгкую ностальгию.
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему
Функция
Почему полуоткрытые интервалы?
Полуоткрытые интервалы позволяют легко "склеивать" смежные диапазоны без риска ошибок на единицу:
- Если
Это работает идеально, потому что конец одного интервала (`b`) автоматически становится началом следующего.
В случае закрытых интервалов, такая "склейка" требует дополнительной обработки:
Связь с индексацией с нуля
Индексация с нуля в Python также связана с этим принципом. Рассмотрим диапазон
- Этот диапазон включает ровно N элементов, что делает код более предсказуемым:
Здесь
Преимущества для работы с массивами
Полуоткрытые интервалы идеально подходят для работы с индексами массивов:
Интервал
Исторический контекст
Этот подход имеет глубокие корни в компьютерной науке. Эдсгер Дейкстра, один из пионеров программирования, в 1982 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными.
📲 Мы в MAX
👉@BookPython
range() в Python использует полуоткрытые интервалы?Функция
range() в Python работает с полуоткрытыми интервалами. Например, range(2, 10) задаёт числа в диапазоне [2, 10), то есть [2, 3, 4, 5, 6, 7, 8, 9]. На первый взгляд это может показаться неочевидным или асимметричным, но у такого подхода есть свои преимущества.Почему полуоткрытые интервалы?
Полуоткрытые интервалы позволяют легко "склеивать" смежные диапазоны без риска ошибок на единицу:
- Если
a = 2, b = 5, и c = 10, то [a, c) можно выразить как:
[a, c) = [a, b) + [b, c)
Это работает идеально, потому что конец одного интервала (`b`) автоматически становится началом следующего.
В случае закрытых интервалов, такая "склейка" требует дополнительной обработки:
[a, c] = [a, b] + [b+1, c]
Связь с индексацией с нуля
Индексация с нуля в Python также связана с этим принципом. Рассмотрим диапазон
range(0, N):- Этот диапазон включает ровно N элементов, что делает код более предсказуемым:
for i in range(0, N):
print(i)
Здесь
i проходит значения от 0 до N-1, что логично и удобно.Преимущества для работы с массивами
Полуоткрытые интервалы идеально подходят для работы с индексами массивов:
arr = [10, 20, 30, 40, 50]
print(arr[1:3]) # [20, 30]
Интервал
[1:3) охватывает элементы с индексами 1 и 2, но не 3, что упрощает вычисления границ.Исторический контекст
Этот подход имеет глубокие корни в компьютерной науке. Эдсгер Дейкстра, один из пионеров программирования, в 1982 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными.
👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Как узнать размер генератора в Python?
В Python часто возникает задача определить размер генератора без необходимости извлечения всех его значений. Это полезно, если вы работаете с большими потоками данных и хотите избежать избыточного расхода памяти.
Пример с len()
Некоторые итераторы, такие как
Однако генераторы не имеют длины, и попытка вызвать
Стандартное решение: преобразование в список
Один из способов получить размер генератора — это преобразовать его в список:
Этот подход работает, но имеет серьёзный недостаток: он требует загрузить все значения генератора в память. Если генератор очень большой, это может привести к нехватке памяти.
Более эффективный подход: подсчёт с помощью sum
Чтобы избежать лишнего расхода памяти, можно подсчитать количество элементов в генераторе с использованием
Этот метод обходит генератор "лениво", не создавая дополнительных списков, что делает его идеальным для работы с большими потоками данных.
Резюме
- Используйте
- Для генераторов избегайте преобразования в список, если важна экономия памяти.
- Используйте
📲 Мы в MAX
👉@BookPython
В Python часто возникает задача определить размер генератора без необходимости извлечения всех его значений. Это полезно, если вы работаете с большими потоками данных и хотите избежать избыточного расхода памяти.
Пример с len()
Некоторые итераторы, такие как
range, поддерживают вызов len():
len(range(10000)) # 10000
Однако генераторы не имеют длины, и попытка вызвать
len() вызовет ошибку:
gen = (x ** 2 for x in range(10000))
len(gen) # TypeError: object of type 'generator' has no len()
Стандартное решение: преобразование в список
Один из способов получить размер генератора — это преобразовать его в список:
gen = (x ** 2 for x in range(10000))
print(len(list(gen))) # 10000
Этот подход работает, но имеет серьёзный недостаток: он требует загрузить все значения генератора в память. Если генератор очень большой, это может привести к нехватке памяти.
Более эффективный подход: подсчёт с помощью sum
Чтобы избежать лишнего расхода памяти, можно подсчитать количество элементов в генераторе с использованием
sum():
gen = (x ** 2 for x in range(10000))
print(sum(1 for _ in gen)) # 10000
Этот метод обходит генератор "лениво", не создавая дополнительных списков, что делает его идеальным для работы с большими потоками данных.
Резюме
- Используйте
len() только для итераторов, поддерживающих его (например, range).- Для генераторов избегайте преобразования в список, если важна экономия памяти.
- Используйте
sum(1 for _ in gen) для эффективного подсчёта элементов генератора.👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💩2
Media is too big
VIEW IN TELEGRAM
Прежде чем читать длиннющий релиз новой версии Python 3.14, посмотрите это видео Евгения Афонасьева, тимлида разработки Antifraud в Авито 🚀
За 12 минут он рассказал, какие фичи стоят внимания внедрения в работу, про небольшие, но приятные обновления тоже не забыл.
📺 Смотрим и обсуждаем по ссылке!
За 12 минут он рассказал, какие фичи стоят внимания внедрения в работу, про небольшие, но приятные обновления тоже не забыл.
Please open Telegram to view this post
VIEW IN TELEGRAM
💩2
Когда вам нужно очистить список в Python, вы, скорее всего, используете
Пример:
Хотя это кажется очевидным, правильное решение стало доступно только с введением метода
До этого для очистки списка приходилось использовать:
-
-
Оба варианта работают, поскольку срезы позволяют модифицировать часть списка. Если вы берёте срез
Теперь же
📲 Мы в MAX
👉@BookPython
lst = []. Однако на самом деле вы просто создаёте новый пустой список и присваиваете его переменной lst, а все другие переменные, которые ссылаются на исходный список, продолжают хранить его содержимое. Пример:
lst = [1, 2, 3]
lst2 = lst
lst = []
print(lst2) # [1, 2, 3]
Хотя это кажется очевидным, правильное решение стало доступно только с введением метода
lst.clear() в Python 3.3. До этого для очистки списка приходилось использовать:
-
del lst[:], или -
lst[:] = [].Оба варианта работают, поскольку срезы позволяют модифицировать часть списка. Если вы берёте срез
[:], он охватывает весь список.Теперь же
lst.clear() является более читаемым и современным решением. 👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2