Python для начинающих
1.06K subscribers
300 photos
3 videos
232 files
62 links
Python для начинающих
Download Telegram
## Schedule — твой персональный дирижёр в мире повторяющихся задач

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

### Что это такое?

Модуль schedule позволяет легко и понятно запускать ваши Python-функции по расписанию: каждый день, каждый час, по выходным или хоть каждую пятую минуту. На вид — как мини-крон прямо внутри кода, только гораздо дружелюбнее.

### Установка

Перед стартом — минутка магии в консоли:

pip install schedule


### Примеры использования

Разберём на пальцах. Допустим, вы хотите, чтобы скрипт отправлял напоминание выпить воды каждый час. Вот как это делается:

import schedule
import time

def remind_water():
print("Time to drink some water!")

schedule.every(1).hour.do(remind_water)

while True:
schedule.run_pending()
time.sleep(1)


Теперь функция remind_water будет срабатывать раз в час, пока скрипт работает.

А если нужно выполнять задачу только по рабочим дням — не проблема!

def check_email():
print("Don't forget to check your email!")

schedule.every().monday.do(check_email)
schedule.every().tuesday.do(check_email)
schedule.every().wednesday.do(check_email)
schedule.every().thursday.do(check_email)
schedule.every().friday.do(check_email)


Можно и покреативить: запускать задачу каждые 10 минут или, скажем, в определённое время суток:

def backup_files():
print("Backup started!")

schedule.every(10).minutes.do(backup_files)
schedule.every().day.at("23:00").do(backup_files)


### Фишки модуля

- schedule.run_pending() проверяет — не пора ли что запустить, и делает это.
- Время можно указывать сразу для нескольких задач с разной периодичностью.
- Работает просто: без лишних настроек, конфигов и заморочек.

### Минусы и ограничения

Модуль не умеет работать в фоне — если закроете скрипт, задачи выполняться не будут. Для продвинутых сценариев (например, для серверов) нужны другие решения, но для учебных и простых домашних проектов schedule — настоящее спасение.

Практикуйте и экспериментируйте, ведь расписание — ключ к продуктивности даже в программировании!
Как настроить локальный сервер с использованием модуля wsgiref
Как настроить локальный сервер с использованием модуля wsgiref
Привет, меня зовут Иван, и сегодня я расскажу тебе, как устроить себе настоящий мини-сервер ― буквально в пару строк! Если ты только начинаешь своё путешествие в мир Python и веба, модуль wsgiref — это твой пропуск на этот интересный уровень.

### Что такое WSGI и зачем он нужен?

WSGI (Web Server Gateway Interface) — это стандарт, который помогает Python-программам общаться с веб-серверами. Встроенный модуль Python wsgiref — это как виртуальный щит, который превращает твой код в простой веб-сервер. Он отлично подходит для тестов и экспериментов — идеально для начинающих!

### Первый пример: “Hello, world!”

Создадим файл server.py:

from wsgiref.simple_server import make_server

def simple_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [b"Hello, world!"]

if __name__ == '__main__':
server = make_server('localhost', 8080, simple_app)
print("Serving on http://localhost:8080/ ...")
server.serve_forever()


Запускай скрипт, переходи в браузере на http://localhost:8080 — и ты увидишь волшебное “Hello, world!”. Именно так начинается путь любого веб-разработчика.

### Как это работает?

- make_server создает сервер и принимает три параметра: адрес, порт и функцию-приложение.
- simple_app — “основное блюдо”. Она получает две переменные: данные о запросе (environ) и функцию для передачи статуса с заголовками (start_response).
- Возвращаемый список содержит байты, которые отдаются в ответ пользователю.

### А если хочется HTML?

Легко! Вот пример функции, отдающей HTML:

def html_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/html; charset=utf-8')]
start_response(status, headers)
html = """
<html>
<head><title>WSGI Test</title></head>
<body><h1>Привет из wsgiref!</h1></body>
</html>
"""
return [html.encode('utf-8')]


### Поддержка разных путей

Хочешь разные ответы по разным URL? Используй environ['PATH_INFO']:

def path_app(environ, start_response):
path = environ.get('PATH_INFO', '/')
if path == '/about':
body = "This is the About page."
else:
body = "Home page."
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [body.encode('utf-8')]


Добавь эту функцию в make_server — и твой сервер стал умнее!

---

Вот так легко можно войти в веб-мир Python, используя стандартные инструменты. Не нужен ни Flask, ни Django, ни танцы с бубном — только чистый Python и твоя фантазия!
👍1
Работа с двоичными файлами: чтение и запись с помощью байтов
Привет! С вами Иван, и сегодня я расскажу о таинственном царстве двоичных (binary) файлов в Python. Мы так привыкли работать с текстом, что забываем: музыка, картинки, да что уж там — даже документ Word — внутри состоят из байтов, а не буковок.

## Чем отличаются двоичные файлы?

Когда мы читаем или пишем файл в текстовом режиме, Python заботится о кодировке: превращает байты в строки и обратно. Но с бинарными данными так не получится — они воспринимаются как сырые байты (bytes). Это важно, если вы, например, работаете с изображениями или сериализуете объекты.

## Как открыть двоичный файл?

Легко! Достаточно добавить к режиму 'r', 'w' или 'a' букву 'b':

with open('example.bin', 'wb') as bin_file:
bin_file.write(b'Hello, world!')


Здесь 'wb' означает write binary — никаких странных символов перевода строки и прочих неожиданностей.

## Чтение двоичных файлов

Открываем файл в режиме 'rb'— читаем байты:

with open('example.bin', 'rb') as bin_file:
data = bin_file.read()
print(data) # Выведет: b'Hello, world!'


Получили на выходе тип bytes. Каждый элемент такого объекта — число от 0 до 255.

## Запись последовательности байтов

Все просто: передаем в write объект bytes или bytearray. Например, сохраним несколько чисел в файл:

numbers = [27, 255, 128, 42]
byte_data = bytes(numbers)
with open('numbers.bin', 'wb') as bin_file:
bin_file.write(byte_data)


## Немного магии с модулем struct

Если нужно упаковать не просто числа, а, например, float или значения разных типов, поможет модуль struct — он превращает числа и структуры в байты и обратно:

import struct

packed = struct.pack('if', 7, 3.14) # 'i' — целое, 'f' — float
with open('struct.bin', 'wb') as bin_file:
bin_file.write(packed)


А вот как распаковать обратно:

with open('struct.bin', 'rb') as bin_file:
data = bin_file.read()
number, value = struct.unpack('if', data)
print(number, value) # 7 3.14


## Итоги

Двоичные файлы — не страшное чудовище, а удобный способ для работы с «сырыми» данными любого типа. Их невозможно случайно «испортить» сменой кодировки, зато можно ловко управлять байтами и экономить место.
👍1
Создание пакетов для повторного использования кода: используем setuptools
Привет! С вами Иван, и сегодня мы разберёмся с созданием собственных Python-пакетов для повторного использования кода c помощью setuptools. Терпеть не могу копировать функции из одного проекта в другой! К счастью, Python позволяет упаковать полезные модули, чтобы потом легко их устанавливать через pip.

## Почему это важно?

Рано или поздно каждый сталкивается с ситуацией: вот отличная функция для обработки даты, и вот она снова нужна — в новом проекте. Перетаскивать файлы вручную – прошлый век! Пакеты решают эту проблему. Помимо удобства, это ещё и первый шаг к публикации в PyPI.

## Минимальный пакет: поехали!

Для примера создадим папку awesome_math, а внутри — файл operations.py:

# operations.py
def add(a, b):
return a + b

def multiply(a, b):
return a * b


Теперь создадим файл __init__.py (даже если он пустой):

# __init__.py
from .operations import add, multiply


Скелет готов!

## Настраиваем setup.py

Теперь самая магия — setup.py:

from setuptools import setup, find_packages

setup(
name="awesome_math",
version="0.1",
packages=find_packages(),
author="Ivan",
description="Sample package for math operations",
python_requires=">=3.6",
)


## Установка пакета

Перейдите в папку выше и установите пакет локально:

pip install -e ./awesome_math


Флаг -e (“editable”) позволяет менять код пакета на лету — удобно для отладки.

## Используем в реальном коде

Готово! Теперь можно импортировать функции из любого места:

from awesome_math import add, multiply

print(add(2, 3)) # 5
print(multiply(4, 5)) # 20


## Итоги

Создавать свои пакеты с помощью setuptools — просто и удобно. Такой подход организует код, ускоряет разработку и позволяет делиться своими наработками с коллегами (или со всем миром!). Я всегда советую автоматизировать повторяющиеся задачи, а свой пакет — лучший способ избавиться от рутины.
👍1
Как работать с унаследованными кодами и библиотеками в Python
Привет! С вами Иван, и сегодня мы разберём одну из самых неоднозначных истин программиста: унаследованный код и сторонние библиотеки — это не враги, а будущие союзники!

Когда впервые сталкиваешься с чужими проектами или старыми библиотеками, кажется, будто попал в таинственный квест без карты. Однако Python предоставляет инструменты, чтобы не только "выжить" среди многолетних конструкций, но и укротить их под свои нужды.

### Исследуем незнакомый код

Для начала важно быстро понять структуру чужой библиотеки. Поможет модуль inspect:

import inspect
import math

print(inspect.getmembers(math, inspect.isfunction))

Этот фрагмент выведет все функции модуля math. Так вы сразу увидите, чем можно воспользоваться, не лезя в исходники.

### Переосмысливаем поведение

Допустим, сторонняя функция работает не совсем так, как хочется. На помощь приходит паттерн "обертки":

from some_old_library import too_simple_func

def my_func(*args, **kwargs):
result = too_simple_func(*args, **kwargs)
if result is None:
raise ValueError("Это слишком просто!")
return result

Такой подход добавляет нужную проверку, не трогая оригинал.

### Замена или расширение классов

Наследуемый класс хранит логику, которую вы бы немного изменили? Подклассируете!

from legacy_package import OldClass

class NewClass(OldClass):
def calculate(self, x):
result = super().calculate(x)
return result * 2

Теперь старый функционал расширен без потери совместимости.

### Отладка без стресса

Модуль logging помогает понять, что происходит внутри:

import logging

logging.basicConfig(level=logging.DEBUG)

def wrapped_func(*args):
logging.debug("Arguments: %s", args)
return too_simple_func(*args)

Логи позволяют действовать осознанно, даже если документация минимальна.

### Важный совет от Ивана

Не бойтесь экспериментировать с чужим кодом (только не в продакшене!). Модули inspect, unittest.mock, обертки и наследование — ваши друзья. С их помощью даже ветхое наследие превратится в прочную базу для новых идей.

До встречи в следующих коротких, но ёмких разборках!
👍1
Автоматизация запуска приложений с PyInstaller
# Автоматизация запуска Python-приложений с PyInstaller

Привет! С вами Иван, и сегодня мы разберём, как сделать запуск ваших Python-приложений быстрым, удобным и "по-взрослому" — одним двойным кликом по файлу. Если вы только начинаете путь в программировании, тема создания исполняемых файлов (.exe на Windows) будет настоящим открытием!

## Для чего нужен PyInstaller?

Когда ваш скрипт готов, часто хочется поделиться им с друзьями или коллегами, которые не знают, что такое Python и как его ставить. Вместо долгих объяснений, как запускать .py файлы, можно собрать из них самостоятельную программу.

PyInstaller превращает ваш Python-код (и все нужные ему библиотеки) в исполняемый файл. Такой файл легко запускать без всяких интерпретаторов и сложно объяснить случайным пользователям, почему по папке не разбросаны всякие .py, .pyc и директории.

## Первое знакомство: Простой пример

Для начала установим PyInstaller:

pip install pyinstaller


Допустим, у вас есть файл hello.py:

def main():
print("Hello, world!")

if __name__ == "__main__":
main()


Соберём из него исполняемый файл:

pyinstaller --onefile hello.py


С ключом --onefile все собирается в один .exe. На выходе получите папку dist/, где и будет ваш долгожданный исполняемый файл.

## Немного креатива: Сохраним иконку и сделаем автозапуск

Вы хотите, чтобы приложение выглядело красивее? Добавьте свою иконку — достаточно добавить флаг:

pyinstaller --onefile --icon=myicon.ico hello.py


А чтобы программа запускалась автоматически при старте системы (например, генерирует полезный отчёт каждое утро), создайте ярлык в папке автозагрузки Windows:

import os
import shutil

startup_dir = os.path.join(os.environ["APPDATA"], "Microsoft", "Windows", "Start Menu", "Programs", "Startup")
shutil.copy("dist/hello.exe", os.path.join(startup_dir, "hello.exe"))


## Обработка ресурсов

PyInstaller поддерживает включение любых необходимых файлов (картинок, настроек и т.п.):

pyinstaller --onefile --add-data "config.yaml;."


## Итог

PyInstaller — отличный инструмент для тех, кто хочет делиться своими проектами без лишней головной боли: собрай, передай файл, и всё работает у любого пользователя. Попробуйте автоматизировать сборку и запуск уже сегодня!
2🔥1
Основы работы с модулем xml.etree.ElementTree для XML-файлов
Привет, друзья! С вами Иван — разгадываем тайны Python каждый день. Сегодня расскажу про отличный инструмент для работы с XML — модуль xml.etree.ElementTree. Это встроенная библиотека Python, которая позволяет парсить, создавать и модифицировать XML-файлы, не нагружая мозг лишней сложностью.

### Как вообще устроен ElementTree?

XML — это способ хранить структурированные данные. Представьте себе дерево: корень, ветви, листья. Модуль ElementTree как раз позволяет “гулять” по этому дереву.

#### Пример 1: Чтение XML

Давайте начнем с простого XML:

<data>
<country name="Russia">
<city>Москва</city>
<city>Санкт-Петербург</city>
</country>
<country name="USA">
<city>New York</city>
<city>Los Angeles</city>
</country>
</data>


Как это прочитать?

import xml.etree.ElementTree as ET

tree = ET.parse('countries.xml')
root = tree.getroot()

for country in root.findall('country'):
name = country.get('name')
print('Country:', name)
for city in country.findall('city'):
print(' City:', city.text)


Вот так просто вытаскиваем все страны и города. Бесплатный бонус — .findall() возвращает подэлементы, а .get() помогает доставать значения атрибутов.

#### Пример 2: Создание XML “с нуля”

А если надо создать свой XML? Не проблема:

import xml.etree.ElementTree as ET

root = ET.Element('library')
book1 = ET.SubElement(root, 'book', title='Python 101')
book2 = ET.SubElement(root, 'book', title='Deep Learning')
ET.SubElement(book1, 'author').text = 'Ivan Petrov'
ET.SubElement(book2, 'author').text = 'Anna Smith'

tree = ET.ElementTree(root)
tree.write('library.xml', encoding='utf-8', xml_declaration=True)


XML-файл готов, структура соблюдена. Заметьте, вместо длинной “ручной” генерации строк — всё строится как дерево объектов.

#### Пример 3: Модификация XML

Надо отредактировать файл? Например, добавить новую книгу:

import xml.etree.ElementTree as ET

tree = ET.parse('library.xml')
root = tree.getroot()

new_book = ET.SubElement(root, 'book', title='Fluent Python')
ET.SubElement(new_book, 'author').text = 'Luciano Ramalho'

tree.write('library.xml', encoding='utf-8', xml_declaration=True)


Новое знание — добавлено!

### Особенности и ограничения

- ElementTree хорош для быстрого старта, но не поддерживает XPath на полную катушку и не валидирует XML.
- Для громоздких и сложных XML ищите что-то “потяжелее” (например, lxml).

Модуль xml.etree.ElementTree — оптимальный старт для тех, кто начал изучать работу с XML на Python. Код читается легко, ошибок — минимум, всё как мы любим!
👍2
- Основы работы с асинхронными итераторами и контекстными менеджерами
Привет! С вами Иван, и сегодня у нас на повестке — асинхронные итераторы и асинхронные контекстные менеджеры в Python. Эти инструменты — не только про «магические» async и await, они воплощают суть современной асинхронности: элегантный контроль над ресурсами и процессами в неблокирующем стиле. Давайте разберёмся по полочкам!

### Асинхронные итераторы

Асинхронный итератор — это объект, который поддерживает метод __anext__ и интерфейс __aiter__, а работать с ним можно через async for. Обычно они нужны, если вы хотите итерироваться по данным, загружаемым с задержками: например, получать ответы от API по мере их поступления.

Вот пример простейшего своего асинхронного итератора:

class AsyncCounter:
def __init__(self, start, end):
self.current = start
self.end = end

def __aiter__(self):
return self

async def __anext__(self):
if self.current >= self.end:
raise StopAsyncIteration
await asyncio.sleep(0.5) # имитация задержки
self.current += 1
return self.current - 1

import asyncio

async def main():
async for number in AsyncCounter(0, 3):
print(number)

asyncio.run(main())


Асинхронные итераторы блестяще подходят, если вы хотите, чтобы программа не простаивала в ожидании внешних данных, а занималась другими делами.

### Асинхронные контекстные менеджеры

А теперь представьте ситуацию: для работы с внешним ресурсом (например, подключение к БД или файлу) вам нужен асинхронный код. Здесь появляются асинхронные контекстные менеджеры (async with), которые реализуют методы __aenter__ и __aexit__.

Пример на основе таймера:

class AsyncTimer:
async def __aenter__(self):
self.start = asyncio.get_event_loop().time()
return self

async def __aexit__(self, exc_type, exc, tb):
end = asyncio.get_event_loop().time()
print(f'Duration: {end - self.start:.2f} seconds')

import asyncio

async def do_work():
await asyncio.sleep(1)

async def main():
async with AsyncTimer():
await do_work()

asyncio.run(main())


Такой подход поможет безопасно выделять и освобождать ресурсы даже в асинхронных задачах. Асинхронные менеджеры активно используют библиотеки aiohttp, aiomysql и другие современные async-инструменты.

### Итог

Асинхронные итераторы и асинхронные контекстные менеджеры — это две стороны одной монеты: грамотное и безопасное управление асинхронными процессами. Освоив их, вы сможете писать «живые» и эффективные приложения, не жертвуя структурой и чистотой кода.

В следующий раз разберём, где на практике искать и как использовать готовые асинхронные инструменты в популярных библиотеках!
👍1
- Как использовать библиотеку joblib для параллельных вычислений
Привет! На связи Иван, и сегодня поговорим о том, как заставить ваш ноутбук работать за троих (или даже десятерых) с помощью Python! Тема выпуска — библиотека joblib и ее простые способы организовать параллельные вычисления.

Постой, зачем мне параллельные вычисления?
Очень просто: если у вас есть повторяющиеся задачи, которые не зависят друг от друга, — например, обработка большого списка изображений или вычисления для разных наборов данных — их можно запускать одновременно. Это ускорит работу почти в разы, особенно на многоядерных процессорах.

Почему joblib, а не стандартный multiprocessing?
joblib проще! Фактически, она создана для тех случаев, когда нужно параллелить обработку данных, начиная от простых циклов до длительных вычислений в Data Science и ML.

Минимальный пример:

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

from joblib import Parallel, delayed

def calc_square_sum(n):
return sum(i * i for i in range(n))

numbers = [10**6, 2 * 10**6, 3 * 10**6, 4 * 10**6]

results = Parallel(n_jobs=2)(delayed(calc_square_sum)(n) for n in numbers)
print(results)


- Parallel(n_jobs=2) — запускаем два параллельных процесса.
- delayed(calc_square_sum)(n) — “оборачиваем” функцию, чтобы она запускалась параллельно для каждого n.

Фишка с joblib:
joblib сам заботится о создании процессов. Просто говорите, сколько “работников” (n_jobs) хотите, и библиотека запустит задачи параллельно.

Параллельная обработка файлов:

import os
from joblib import Parallel, delayed

def process_file(filename):
# Тут могут быть чтение, обработка, парсинг и т.п.
return os.path.getsize(filename)

file_list = ['file1.txt', 'file2.txt', 'file3.txt']
sizes = Parallel(n_jobs=3)(delayed(process_file)(fname) for fname in file_list)
print(sizes)


Когда joblib особенно полезна?
- При работе с большими наборами данных.
- Для ускорения преобразований в циклах.
- Для сложных аналитических вычислений.

joblib также отлично “дружит” с библиотеками для машинного обучения, например, scikit-learn, в котором многие функции используют joblib внутри!

Попробуйте joblib, если хочется ускорить рутинные задачи и “разогнать” свои вычисления за пару строк кода!
👍1
- Введение в структурированное логирование с помощью модуля logging
Привет! Меня зовут Иван, и сегодня мы разберём одну из самых недооценённых суперспособностей 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 поближе, и ваши проекты станут на порядок “взрослее”!

Ваш Иван.
👍2