Б
Библиотека Python разработчика | Книги по питону
08.10.2026 05:06 · 👁 400
Если вы создаёте новые объекты внутри метода __init__, возможно, будет лучше передавать их как аргументы и использовать фабричный метод. Это позволяет разделить бизнес-логику и технические детали создания объектов.
В этом примере __init__ принимает host и port для создания подключения к базе данных:
class Query:
def __init__(self, host, port):
self._connection = Connection(host, port)
Возможный рефакторинг:
class Query:
def __init__(self, connection):
self._connection = connection
@classmethod
def create(cls, host, port):
return cls(Connection(host, port))
Такой подход имеет как минимум следующие преимущества:
• Упрощает внедрение зависимостей. В тестах можно использовать Query(FakeConnection()).
• Класс может иметь столько фабричных методов, сколько нужно; подключение может создаваться не только по host и port, но и путём клонирования другого подключения, чтения конфигурационного файла или объекта, использования значения по умолчанию и т.д.
• Такие фабричные методы можно сделать асинхронными; это невозможно для __init__.
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
06.10.2026 05:38 · 👁 616
Чтобы сохранить любую информацию в памяти или на устройстве хранения, её необходимо представить в виде байтов. Python, как правило, предоставляет уровень абстракции, при котором вы оперируете непосредственно данными, а не их байтовым представлением.
Тем не менее, когда вы, скажем, записываете строку в файл, вы работаете с физической структурой данных. Чтобы поместить символы в файл, их нужно преобразовать в байты — это называется кодированием. Когда вы получаете байты из файла, скорее всего, вы захотите превратить их в осмысленные символы — это называется декодированием.
Существует сотни методов кодирования. Самый популярный — вероятно, Unicode, но он сам по себе не может преобразовывать данные в байты. В смысле байтового представления Unicode вообще не является кодировкой. Unicode определяет соответствие между символами и их числовыми кодами. Например, 🐍 имеет код 128013.
Но чтобы записать числа в файл, нужна настоящая кодировка. Unicode обычно используется вместе с utf-8, которая (в большинстве случаев) является стандартной в Python. При чтении из файла Python автоматически декодирует utf-8. Вы можете выбрать любую другую кодировку с помощью параметра encoding= функции open, либо читать «сырые» байты, добавив b к режиму открытия файла.
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
05.10.2026 09:19 · 👁 707
В Python очень короткий список встроенных констант. Одна из них — Ellipsis, которую также можно записать как .... Эта константа не имеет особого значения для интерпретатора, но используется в местах, где такой синтаксис выглядит уместно.
Библиотека NumPy поддерживает Ellipsis в качестве аргумента __getitem__, например: x[...] возвращает все элементы массива x.
PEP 484 придаёт Ellipsis дополнительное значение: Callable[..., type] — это способ определить тип вызываемых объектов без указания типов аргументов.
Наконец, ... можно использовать, чтобы обозначить, что функция ещё не реализована. Это абсолютно валидный код на Python:
def x():
...
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
02.10.2026 06:28 · 👁 804
Обработка исключений в асинхронных программах может быть непростой задачей.
В asyncio, если корутина выбрасывает исключение, оно передаётся в тот код, который ожидает соответствующий future. Если await вызывается в нескольких местах, то каждое из них получит это исключение (так как оно сохраняется внутри объекта исключения). Следующий код напечатает сообщение об ошибке пять раз:
import asyncio
async def error():
await asyncio.sleep(1)
raise ValueError()
async def waiter(task):
try:
await task
except ValueError:
print('error')
else:
print('OK')
async def main():
task = asyncio.get_event_loop().create_task(error())
for _ in range(5):
asyncio.get_event_loop().create_task(waiter(task))
await asyncio.sleep(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Если исключение выброшено, но задача (task) ни разу не была ожидаема (awaited), исключение будет потеряно. В таком случае при уничтожении задачи вы получите предупреждение: “Task exception was never retrieved”.
Когда вы используете await asyncio.gather(tasks) и одна из задач выбрасывает исключение, оно передаётся наружу. Однако если несколько задач выбросят исключения, вы получите только первое, остальные будут проигнорированы:
import asyncio
async def error(i):
await asyncio.sleep(1)
raise ValueError(i)
async def main():
try:
await asyncio.gather(
error(1),
error(2),
error(3),
)
except ValueError as e:
print(e)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Вы можете использовать gather с параметром return_exceptions=True, чтобы получать исключения как обычные значения. Следующий код напечатает: [42, ValueError(2,), ValueError(3,)]
import asyncio
async def error(i):
await asyncio.sleep(1)
if i > 1:
raise ValueError(i)
return 42
async def main():
results = await asyncio.gather(
error(1),
error(2),
error(3),
return_exceptions=True,
)
print(results)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
30.09.2026 06:44 · 👁 854
Как отлаживать Python-код, не выходя из редактора - с помощью встроенного модуля pdb.
🔍 Быстрая отладка с pdb
Часто, когда код не работает как надо, мы начинаем закидывать print()-ами. Но это неудобно, медленно и мусорит код. Вместо этого вставь в нужное место строчку:
import pdb; pdb.set_trace()
Когда выполнение дойдет до этой строки, ты попадешь в интерактивную консоль отладчика прямо в терминале. Дальше можно:
- n (next) — перейти к следующей строке;
- s (step) — зайти внутрь функции;
- c (continue) — продолжить выполнение;
- l (list) — показать текущий контекст;
- p var — вывести значение переменной var.
💡 Пример
def calc(a, b):
import pdb; pdb.set_trace()
result = a + b
return result
calc(2, 3)
На строке с pdb.set_trace() ты остановишься и сможешь изучить, что происходит внутри.
Зачем это нужно?
- Понять, почему что-то идет не так.
- Посмотреть, какие значения у переменных прямо в момент ошибки.
- Быстро отладить без запуска IDE - удобно в Docker, SSH или при работе с cron.
Попробуй - один раз освоишь, и уже не захочешь возвращаться к print().
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
28.09.2026 08:34 · 👁 961
Python поддерживает цепочные присваивания со следующим синтаксисом:
a = b = c = 42
Выглядит как цепочка присваиваний в C, но работает совершенно иначе. В C результат одного присваивания используется в следующем:
a = (b = (c = 42))
В Python всё не так. Операция присваивания не возвращает результат — это оператор, а не выражение. Вместо этого происходит несколько присваиваний слева направо:
2 0 LOAD_CONST 1 (42)
2 DUP_TOP
4 STORE_FAST 0 (a)
6 DUP_TOP
8 STORE_FAST 1 (b)
10 STORE_FAST 2 (c)
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
27.09.2026 08:45 · 👁 949
Чтобы объект можно было использовать в качестве ключа словаря, он должен быть хешируемым. Хешируемые объекты поддерживают метод __hash__, который возвращает целое число. Для получения хеша значения используется встроенная функция hash.
Встроенные типы, которые являются неизменяемыми, по умолчанию хешируемы. Все пользовательские объекты тоже хешируемы, но есть нюанс. Если вы определяете метод __eq__ для своего типа, то вы также должны определить __hash__ таким образом, чтобы hash(a) == hash(b) для всех a и b, которые считаются равными. Нарушение этого правила может привести к некорректной работе словаря:
class A:
def __init__(self, x):
self.x = x
def __hash__(self):
return random.randrange(10000)
def __eq__(self, other):
return self.x == other.x
d = {}
d[A(2)] = 2
d.get(A(2), 0)
# Вывод: 0
Обратите внимание: как только вы определяете __eq__ в классе, реализация __hash__ по умолчанию удаляется, так как она больше не подходит (по умолчанию все значения считаются неравными).
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
25.09.2026 06:42 · 👁 1K
Как быстро очистить список в Python?
Сегодня я покажу вам несколько способов очистки списка в Python и расскажу, какой вариант лучше в зависимости от ситуации.
1️⃣ Присвоение пустого списка
lst = [1, 2, 3, 4, 5]
lst = []
Этот способ создаёт новый пустой список, но старая ссылка остаётся в памяти, если на неё есть другие ссылки.
2️⃣ Использование .clear()
lst = [1, 2, 3, 4, 5]
lst.clear()
Метод .clear() очищает список на месте, не создавая новый объект. Это предпочтительный способ, если список используется в нескольких местах.
3️⃣ Использование del
lst = [1, 2, 3, 4, 5]
del lst[:]
Работает аналогично .clear(), но выглядит чуть менее очевидно.
4️⃣ Удаление списка полностью
lst = [1, 2, 3, 4, 5]
del lst
Этот вариант полностью удаляет переменную lst. Если потом попробовать к ней обратиться, будет ошибка NameError.
🔹 Какой способ лучше?
• Если нужно просто очистить список, используйте .clear().
• Если хотите заменить его новым объектом - lst = [].
• del lst[:] – редкий вариант, но возможен.
• del lst подходит, если список больше не нужен в программе.
Какой вариант используете вы? Пишите в комментариях!
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
24.09.2026 06:43 · 👁 844
🚀 5 крутых Python-фишек, о которых знают не все
Python — мощный и удобный язык, но даже опытные разработчики иногда не знают всех его возможностей. Сегодня я покажу пять полезных трюков, которые могут упростить вашу работу.
1. Используем else в for и while
Многие не знают, что в Python циклы for и while могут иметь блок else. Он выполняется, если цикл не был прерван через break.
✅ Пример:
numbers = [1, 3, 5, 7]
for num in numbers:
if num % 2 == 0:
print("Есть чётное число!")
break
else:
print("Чётных чисел нет.")
🔹 Если в списке нет чётных чисел, сработает else.
2. "Распаковка" переменных
В Python можно присваивать сразу несколько значений одной строкой.
✅ Пример:
a, b, c = 1, 2, 3
print(a, b, c) # 1 2 3
Можно менять местами значения без временной переменной:
x, y = 5, 10
x, y = y, x
print(x, y) # 10 5
3. Используем _ в больших числах
Чтобы числа легче читались, можно разделять разряды _.
✅ Пример:
big_number = 1_000_000_000
print(big_number) # 1000000000
Это просто синтаксический сахар, Python игнорирует _ при вычислениях.
4. Получаем значение из словаря с запасным вариантом
Вместо if key in dict можно использовать .get(), чтобы избежать KeyError.
✅ Пример:
user_data = {"name": "Alice"}
age = user_data.get("age", 18) # Если ключа "age" нет, вернётся 18
print(age) # 18
5. "Распаковка" списка в аргументы функции
Оператор * позволяет передавать элементы списка в функцию как отдельные аргументы.
✅ Пример:
def greet(name, age):
print(f"Привет, {name}! Тебе {age} лет.")
user_info = ["Иван", 25]
greet(*user_info) # Привет, Иван! Тебе 25 лет.
То же работает со словарями через **:
user_dict = {"name": "Ольга", "age": 30}
greet(**user_dict)
Эти фишки делают код лаконичнее и понятнее.
📲 Мы в MAX
👉@BookPython
Б
Библиотека Python разработчика | Книги по питону
23.09.2026 05:32 · 👁 842
🔥 Как ускорить Python-код в 10 раз?
Сегодня покажу вам мощный инструмент для оптимизации кода - Numba. Это библиотека, которая позволяет компилировать Python-функции в машинный код, используя JIT-компилятор.
🚀 Как это работает?
Numba использует LLVM для компиляции кода во время выполнения, превращая Python в код, близкий по скорости к C.
Пример
Допустим, у нас есть функция, вычисляющая сумму квадратов чисел:
import numpy as np
import time
def sum_of_squares(n):
result = 0
for i in range(n):
result += i ** 2
return result
n = 10**7
start = time.time()
sum_of_squares(n)
print("Обычный Python:", time.time() - start)
Теперь ускорим её с помощью Numba:
from numba import jit
@jit(nopython=True)
def sum_of_squares_numba(n):
result = 0
for i in range(n):
result += i ** 2
return result
start = time.time()
sum_of_squares_numba(n)
print("С Numba:", time.time() - start)
📊 Результат:
✅ Код на чистом Python выполняется ~5-10 раз медленнее, чем с Numba.
✅ Numba особенно полезна для математических вычислений и обработки массивов.
✅ Простая аннотация @jit(nopython=True) уже даёт мощный прирост скорости!
Где применять?
✔ Численные расчёты
✔ Обработку данных
✔ Алгоритмы машинного обучения
Попробуйте Numba и напишите в комментариях, удалось ли вам ускорить свой код!
📲 Мы в MAX
👉@BookPython