Python, питон - статьи о программировании
По поводу покупки рекламы - @solkogan
Библиотека: @pyknigi
Примеры программ: @pysamples
Мой сайт: pythonvideo.ru
Информация о канале обновлена 22.08.2025.
Python, питон - статьи о программировании
По поводу покупки рекламы - @solkogan
Библиотека: @pyknigi
Примеры программ: @pysamples
Мой сайт: pythonvideo.ru
Привет! Меня зовут Иван, и сегодня мы разберём одну из самых недооценённых суперспособностей Python — структурированное логирование! Если вы уже сталкивались с модулем logging, но всегда ограничивались парой строчек для отладки, пришло время поднять левел вашего кода.
### Зачем вообще нужен logging?
Стандартный модуль logging позволяет не просто печатать информацию для “себя” в отладочных целях, а организовать работу вашего приложения так, чтобы логи были читаемыми, информативными и пригодными для автоматической обработки. Это особенно важно, если проект растёт, а в команде появляется ещё кто-то кроме вас.
### Быстрая стартовая конфигурация
Давайте сравним простую запись через print()
и использование logging:
import logging
logging.basicConfig(level=logging.INFO)
logging.info("User logged in")
Казалось бы, разница невелика. Но давайте добавим структуру!
### Форматируем логи под свои нужды
С помощью format
можно задать, что и как выводить:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(name)s — %(message)s'
)
logging.info("Processing data...")
Теперь в логе — время, уровень сообщения, имя логгера, текст. Попробуйте добавить имя модуля или, например, идентификатор пользователя.
### Структурирование через дополнительный контекст
Ценность логирования растёт, когда можно структурировать данные: например, выводить идентификаторы заказов, пользователей и даже JSON.
import logging
logger = logging.getLogger("auth")
extra_info = {'user_id': 123, 'ip': '192.168.0.1'}
logger.info("Login attempt", extra=extra_info)
Чтобы extra-данные появились в выводе, их нужно добавить в формат:
logging.basicConfig(
format='%(asctime)s [%(levelname)s] %(name)s — %(message)s [User: %(user_id)s IP: %(ip)s]'
)
### Логирование в JSON (ещё шаг к структуре)
Используя сторонние библиотеки типа python-json-logger
, формат можно сделать пригодным для автоматической обработки:
from pythonjsonlogger import jsonlogger
import logging
handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
handler.setFormatter(formatter)
logger = logging.getLogger("myjsonlogger")
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info("Event processed", extra={'event_id': 555, 'status': 'success'})
### Вывод
Структурированное логирование позволит не теряться в море сообщений даже в большом проекте: вы сможете сортировать, фильтровать и анализировать свои логи как профи. Не ограничивайтесь print’ом — знакомьтесь с logging поближе, и ваши проекты станут на порядок “взрослее”!
Ваш Иван.
Привет, друзья! С вами Иван, и сегодня мы погрузимся в захватывающий мир многопоточности на Python с помощью модуля threading
. Даже если вы пока не запускали код "параллельно", этот пост для вас!
### Что такое потоки и зачем они нужны?
Обычно Python выполняет код последовательно. Но что если вам нужно скачивать картинки, опрашивать API и тут же обновлять интерфейс? Здесь на сцену выходит threading
— стандартный модуль для работы с потоками. Потоки (threads) позволяют запускать функции параллельно, не ожидая завершения одной, чтобы стартовать другую.
### Простой пример: запуск двух задач одновременно
Посмотрим, как это выглядит на практике:
import threading
import time
def print_numbers():
for i in range(5):
print(f"Number: {i}")
time.sleep(1)
def print_letters():
for letter in 'abcde':
print(f"Letter: {letter}")
time.sleep(1)
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)
t1.start()
t2.start()
t1.join()
t2.join()
print("Done!")
Две функции работают параллельно: одна выводит числа, другая — буквы.
### Как управлять потоками?
- Создание: каждый поток — это экземпляр threading.Thread
, который принимает функцию через параметр target
, и ее аргументы через args
.
- Запуск: .start()
начинает выполнение в новом потоке.
- Ожидание завершения: .join()
блокирует основной поток, пока дочерний не закончится.
### А если нужно знать, работает ли поток?
worker = threading.Thread(target=time.sleep, args=(3,))
worker.start()
print(worker.is_alive()) # True
worker.join()
print(worker.is_alive()) # False
Метод is_alive()
вернет True
, пока поток еще трудится.
### Безопасность данных — используем Lock
Потоки могут обращаться к одним и тем же данным, поэтому важно использовать блокировки (Lock
):
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(1000):
with lock:
counter += 1
threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # Всегда 10000!
Lock
гарантирует, что только один поток изменяет переменную в конкретный момент.
---
threading
открывает путь к одновременному исполнению кода и ускоряет задачи ввода-вывода. Главное — не забывайте про безопасный доступ к общим данным, и тогда ваши приложения станут гораздо мощнее!
Привет! На связи Иван, и сегодня в нашем блоге разберём магию перенаправления потоков ввода и вывода в Python. Зачем это нужно? Например, если вы хотите записывать вывод вашей программы не только на экран, но и в файл, или "обмануть" функцию, которая традиционно ждёт пользовательский ввод, подсовывая ей данные автоматически. Готовы? Погнали!
## Перенаправляем stdout: вывод в файл и обратно
Для работы с потоками в Python служит модуль sys
. Самый популярный поток — это sys.stdout
, который по умолчанию пишет в консоль. Давайте заставим его писать в файл:
import sys
with open('output.txt', 'w') as file:
original_stdout = sys.stdout # сохраняем ссылку на стандартный поток
sys.stdout = file # перенаправляем stdout в файл
print("Hello, file!")
sys.stdout = original_stdout # возвращаем stdout обратно
print("Hello, console!")
Теперь строка "Hello, file!" попадёт в файл, а "Hello, console!" — как обычно, в терминал.
## Подменяем stdin: автоматизируем ввод
Точно так же можно подменить поток ввода. Это удобно, когда нужно тестировать функции, требующие input от пользователя.
import sys
from io import StringIO
test_input = StringIO('42\n')
original_stdin = sys.stdin
sys.stdin = test_input
number = int(input("Enter a number: "))
print("Number x2:", number * 2)
sys.stdin = original_stdin
В этом примере input не ждёт ввода, а сразу получает '42'. Удобно для юнит-тестов!
## А если хочется перехватить вывод программы?
Трюк с подменой stdout особенно крут, когда хочется легко перехватывать и анализировать результат работы каких-то функций. Например, сделаем функцию, возвращающую всё, что она напечатала:
def capture_output(func):
import sys
from io import StringIO
output = StringIO()
original_stdout = sys.stdout
sys.stdout = output
try:
func()
finally:
sys.stdout = original_stdout
return output.getvalue()
def hello():
print("Hello from function!")
text = capture_output(hello)
print("Captured:", text)
Теперь мы можем обработать результат как строку — не круто ли?
На этом всё! Не стесняйтесь экспериментировать с потоками: это ключ к автоматизации, тестированию и оптимизации ваших программ. Желаю отличной практики и новых открытий с Python!
Иван.
Привет! На связи Иван, и сегодня мы разоблачим один из «секретных агентов» стандартной библиотеки Python — модуль struct. Если вам хоть раз приходилось работать с бинарными файлами или протоколами низкого уровня, struct станет вашим лучшим другом. Без него не получится удобно преобразовывать структурированные данные в байты и обратно. Давайте разберёмся, что к чему, на конкретных примерах.
## Быстро обо всём: для чего нужен struct?
Модуль struct позволяет «упаковать» данные в байтовые строки (bytes) и «распаковать» их обратно в привычные питоновские типы. Это незаменимо, если нужно, например, сериализовать числа для передачи по сети или сохранить данные так, чтобы их потом мог прочитать C-программа.
## Основные приёмы
Всё крутится вокруг функций pack
и unpack
, а также строки формата, описывающей, как упаковать данные.
### Пример 1: Запаковать числа в байты
import struct
data = (42, 3.14)
packed = struct.pack('if', *data) # i — int, f — float
print(packed) # что-то вроде b'*\x00\x00\x00\xc3\xf5H@'
# А теперь обратно:
unpacked = struct.unpack('if', packed)
print(unpacked) # (42, 3.140000104904175)
### Пример 2: Работа с бинарными файлами
with open('data.bin', 'wb') as f:
f.write(struct.pack('I2c', 2024, b'P', b'y'))
with open('data.bin', 'rb') as f:
content = f.read()
print(struct.unpack('I2c', content)) # (2024, b'P', b'y')
### Пример 3: Парсинг байтов вручную
Часто приходят сырые байты откуда-то (например, из сети).
msg = b'\x05\x00\x00\x00hello' # длина строки (5), затем сама строка
length = struct.unpack('I', msg[:4])[0]
text = msg[4:4+length].decode()
print(length, text) # 5 hello
## Вывод
struct
полезен там, где нужно строго соблюдать размер и формат данных. Для низкоуровневой магии или общения с «железом» — вещь незаменимая. Главное — освоиться с форматами (i
, f
, c
, h
, и так далее), и тогда любой бинарный файл у вас — как открытая книга!
Привет! Я Иван, и сегодня мы с тобой шагнем в загадочный мир работы с электронной почтой из Python – научимся подключаться к POP3-серверам! Почему это важно? Иногда автоматическая обработка почты нужна для создания ботов, триггеров или просто творческих проектов.
POP3 – это популярный протокол, позволяющий "забирать" письма с серверов электронной почты. Для работы с ним есть стандартный модуль poplib
. Давай разберём его на практике.
### 1. Установка соединения
import poplib
server = poplib.POP3_SSL('pop.gmail.com', 995)
server.user('your_email@gmail.com')
server.pass_('your_app_password')
В современных почтовиках, например Gmail, потребуется пароль приложения (генерируется в настройках безопасности).
### 2. Получаем список писем
num_messages = len(server.list()[1])
print(f'You have {num_messages} messages.')
server.list()
возвращает список всех писем в почтовом ящике.
### 3. Читаем первое письмо
resp, lines, octets = server.retr(1) # 1 — это номер письма
message_content = b'\n'.join(lines).decode('utf-8')
print(message_content)
retr(n)
берёт письмо по номеру. Письмо возвращается в виде списка байтовых строк (lines), которые мы соединяем и декодируем.
### 4. Завершаем сессию
server.quit()
---
В реальных задачах удобно обрабатывать письма не по номерам, а в цикле, или искать определённые заголовки. Также для красивого разбора структуры письма пригодятся модули email
и re
– но об этом уже в другой раз.
Совет: Проверяй настройки безопасности почтового ящика! Иногда нужно разрешить подключение со сторонних приложений.
Работа с POP3 – открывает путь к автоматизации и аналитике писем (например, уведомлений о заказах или сообщений от пользователей). Удачного кодинга и до скорых встреч!
Владелец канала не предоставил расширенную статистику, но Вы можете сделать ему запрос на ее получение.
Также Вы можете воспользоваться расширенным поиском и отфильтровать результаты по каналам, которые предоставили расширенную статистику.
Также Вы можете воспользоваться расширенным поиском и отфильтровать результаты по каналам, которые предоставили расширенную статистику.
Подтвердите, что вы не робот
Вы выполнили несколько запросов, и прежде чем продолжить, мы ходим убелиться в том, что они не автоматизированные.