Python для начинающих
1.24K subscribers
546 photos
3 videos
232 files
74 links
Python для начинающих
Download Telegram
Привет! С вами Иван, и сегодня у нас на повестке — асинхронные итераторы и асинхронные контекстные менеджеры в 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 поближе, и ваши проекты станут на порядок “взрослее”!

Ваш Иван.
👍3
- Использование SQLAlchemy для управления транзакциями в базах данных
Привет, на связи Иван! Сегодня поговорим о магии управления транзакциями с помощью SQLAlchemy — универсального инструмента для работы с базами данных в Python.

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

SQLAlchemy не только помогает строить запросы к базе «на лету», но и позволяет контролировать целостность данных через механизмы управления транзакциями.

### Пример 1: Автоматическое управление транзакциями

Всё просто: используем контекстный менеджер session.begin(). Если внутри блока возникает исключение — все изменения автоматом откатываются.

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, Session

Base = declarative_base()

class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)

engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)

with Session(engine) as session:
with session.begin():
new_user = User(name='Alice')
session.add(new_user)
# Закоммитили — пользователь добавлен!


### Пример 2: Ручной контроль — commit и rollback

Иногда нужно больше контроля, например, при сложной логике:

with Session(engine) as session:
try:
user1 = User(name='Bob')
session.add(user1)
# Какая-то логика, возможно, с ошибкой
if user1.name == 'Bob':
raise ValueError("Test error!")
session.commit()
except Exception:
session.rollback()
print("Транзакция отменена, все изменения откатились.")


### Преимущества

- Надежность: можно быть уверенным, что данные не останутся в «полусыром» состоянии.
- Удобство: Pythonic API и защита от ошибок.
- Гибкость: поддержка разных СУБД (PostgreSQL, SQLite, MySQL и др.).

SQLAlchemy превращает работу с транзакциями во вполне дружелюбное и безопасное занятие. Теперь вы знаете, как избегать неожиданных неприятностей при работе с базами данных на Python. Попробуйте — понравится!
👍3
- Как внедрить обработку изображений в веб-приложение на Python
Привет! На связи Иван. Сегодня разберём, как добавить возможность обработки изображений в ваше Python-веб-приложение. Это реальный must-have, если вы хотите, чтобы пользователи могли загружать фото и редактировать их прямо в браузере.

Модули, которые нам пригодятся — это Flask для сервера и легендарный Pillow для обработки изображений. Да, всё проще, чем кажется!

## Установка

Установим нужные библиотеки:

pip install flask pillow


## Базовое приложение, принимающее изображение

Сначала напишем простейший сервер:

from flask import Flask, request, send_file
from PIL import Image
import io

app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def process_image():
if 'file' not in request.files:
return "No file uploaded", 400
img_file = request.files['file']
img = Image.open(img_file.stream)
# Применим простую обработку: например, повернём изображение
img = img.rotate(90, expand=True)
buf = io.BytesIO()
img.save(buf, format='JPEG')
buf.seek(0)
return send_file(buf, mimetype='image/jpeg')

if __name__ == "__main__":
app.run(debug=True)


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

1. Пользователь отправляет картинку на /upload через POST-запрос.
2. Сервер открывает изображение с помощью Pillow.
3. Обрабатывает изображение (здесь — поворот на 90 градусов).
4. Возвращает обработанный файл пользователю.

## Немного больше магии

А вот как сделать превью картинки:

img = Image.open(img_file.stream)
img.thumbnail((128, 128))


А если хотите фильтр «чёрно-белое фото» — это одна строчка:

img = img.convert('L')


## Как попробовать?

Можно использовать Postman или curl:

curl -F "file=@your_image.jpg" http://127.0.0.1:5000/upload --output result.jpg


## Краткие советы

- Всегда проверяйте формат изображения!
- Защитите приложение от загрузки слишком больших файлов.
- Pillow поддерживает кучу фильтров и манипуляций: кадрирование, размытие, изменение яркости и многое другое.

Обработка изображений в веб-приложениях на Python — вопрос пары строчек кода. Главное — фантазия и понимание, как устроен ваш стек. Экспериментируйте, и пусть ваше приложение станет стильнее и удобнее!

До встречи,
Иван
- Введение в модуль PyPDF2 для работы с PDF-документами
Привет! С вами Иван, и сегодня мы заглянем под обложку одного из самых популярных форматов для документов — PDF. Если вы думали, что читать, объединять или вырезать страницы из PDF — это удел только офисных программ, то пришло время познакомиться с модулем PyPDF2 в Python!

Что такое PyPDF2?

PyPDF2 — это пакет, который позволяет легко обрабатывать PDF-файлы: читать, извлекать текст, собирать вместе разные документы и даже защищать их паролем. Звучит как магия? Давайте попробуем на практике.

### Чтение PDF: быстро и просто

Допустим, у вас есть файл sample.pdf, и вы хотите вывести его содержимое на экран. Всё элементарно:

import PyPDF2

with open('sample.pdf', 'rb') as file:
pdf_reader = PyPDF2.PdfReader(file)
page = pdf_reader.pages[0]
print(page.extract_text())


Вот и всё! Открыли, прочитали первую страницу, вывели текст. Никаких танцев с бубном.

### Склейка документов: дела объединённые

Хотите объединить несколько PDF-файлов в один? Смотрите, как это делается:

import PyPDF2

merger = PyPDF2.PdfMerger()
for pdf in ['file1.pdf', 'file2.pdf']:
merger.append(pdf)

with open('merged.pdf', 'wb') as output:
merger.write(output)


Вуаля! Теперь merged.pdf содержит страницы обоих исходных файлов. Быстро, изящно и удобно.

### Извлечение страниц: никаких лишних листов

Бывает, надо сохранить только несколько нужных страниц. За это отвечает PdfWriter:

import PyPDF2

reader = PyPDF2.PdfReader('big.pdf')
writer = PyPDF2.PdfWriter()
for num in [0, 2]: # Например, 1-я и 3-я страницы
writer.add_page(reader.pages[num])

with open('extracted.pdf', 'wb') as out:
writer.write(out)


Теперь у вас новый PDF только с выбранными страницами!

### Безопасность: ставим пароль

Если хочется оставить секретные заметки только для себя:

import PyPDF2

reader = PyPDF2.PdfReader('open.pdf')
writer = PyPDF2.PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.encrypt('StrongPassword!')

with open('protected.pdf', 'wb') as out:
writer.write(out)


Теперь открыть protected.pdf без пароля не получится.

---

PyPDF2 делает работу с PDF простой и гибкой, как и должно быть в Python. Приложения — на любой вкус: отчеты, автоматизация документов, просто эксперименты. Надеюсь, этот краткий обзор вдохновит вас на новые проекты!
👍2
- Сериализация данных с использованием модуля json и pickle
Привет! Я Иван, и сегодня мы окунемся в мир сериализации данных в Python с помощью двух мощных модулей: json и pickle. Если вы когда-нибудь задумывались, как сохранить сложные структуры данных в файл, а позже быстро их восстановить — этот пост для вас.

### Сериализация: зачем это нужно?

Сериализация — это процесс преобразования объектов в поток байтов или строк, чтобы их можно было хранить или передавать. А потом — обратно в объекты с помощью десериализации. В Python из коробки есть два популярных инструмента для этих задач: json и pickle.

---

## Модуль json: стандарт для обмена

json переводит объекты Python в строку в формате JSON и обратно. Это удобно, если ваши данные нужно читать или писать из других языков программирования.

### Пример: сериализация и десериализация словаря

import json

data = {"name": "Alice", "age": 30, "is_active": True, "hobbies": ["music", "python"]}
# Сериализация: запись в строку
json_str = json.dumps(data)
print(json_str)

# Десериализация: из строки обратно в Python-объект
new_data = json.loads(json_str)
print(new_data)


Кроме строк, можно сразу работать с файлами:

with open("data.json", "w") as f:
json.dump(data, f)


И обратно:

with open("data.json") as f:
data_from_file = json.load(f)


---

## Модуль pickle: для хранения любых объектов

pickle — это уже магия посерьезней. Он умеет сериализовать почти любые объекты Python (и даже функции), но полученные данные будут не человекочитаемыми и небезопасны для загрузки из неизвестных источников.

### Пример: сериализация класса

import pickle

class User:
def __init__(self, username):
self.username = username

user = User('Bob')

# Сохраняем объект в файл
with open("user.pkl", "wb") as f:
pickle.dump(user, f)

# Загружаем объект обратно
with open("user.pkl", "rb") as f:
loaded_user = pickle.load(f)
print(loaded_user.username)


---

## json или pickle: что выбрать?

- json: для обмена между разными языками и системами, когда важна читаемость.
- pickle: для хранения сложных структур Python, когда безопасность не критична.

Используйте правильный инструмент — и ваши данные всегда будут под рукой!

До встречи в следующих постах!
— Иван
👍2
- Использование doctest для тестирования документации и кода
Привет! С вами Иван, и сегодня мы рассмотрим один из самых недооценённых инструментов стандартной библиотеки Python — модуль doctest. Даже если вы только начали своё знакомство с языком, вы наверняка уже сталкивались с примерами кода прямо в документации функций. Так вот, doctest умеет запускать такие примеры и проверять, всё ли работает именно так, как написано!

Зачем это нужно?
Во-первых, тесты прямо в строках документации помогают другим разработчикам понять, как на самом деле использовать вашу функцию. Во-вторых, если вы со временем поменяете реализацию, doctest сразу заметит, если что-то стало работать иначе.

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

Допустим, у нас есть вот такая функция:

def multiply(a, b):
"""
Multiply two numbers.

Example:
>>> multiply(2, 3)
6
>>> multiply(-1, 5)
-5
"""
return a * b


Вот и всё! Мы вписали примеры прямо в docstring. Теперь проверяем их командой в консоли:

python -m doctest my_module.py


Если всё хорошо, doctest молча промолчит, но как только что-то идёт не так — покажет на ошибку.

## А если ситуация сложней?

Даже нестандартные случаи можно покрыть doctest’ом, например:

def divide(a, b):
"""
Divide a by b.

>>> divide(6, 2)
3.0
>>> divide(5, 0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
"""
return a / b


Появилась ошибка? Просто пропишите её в docstring, уточняя только последние строки traceback — doctest это поймёт.

## Автоматизация

Можно запускать тесты не только через консоль. Например, так:

if __name__ == "__main__":
import doctest
doctest.testmod()


Теперь doctest сам проверит все функции при запуске скрипта.

## Итоги

doctest — быстрый способ держать документацию и рабочий код в актуальном состоянии. Особенно удобен на этапе написания простых функций и модулей. Не забывайте про этот инструмент, и ваш код будет не только функциональным, но и понятным для всех!

До встречи в следующих постах — будем исследовать Python дальше!
👍2
- Как создавать интерактивные потоковые приложения с Streamlit
Привет, друзья! На связи Иван, и сегодня у нас настоящая находка для тех, кто хочет оживить свои Python-проекты — мы поговорим о Streamlit.

Streamlit — это библиотека, которая позволяет создавать интерактивные веб-приложения на Python буквально за считанные минуты. Не нужны ни знания фронтенда, ни написание HTML/CSS. Всё, что нужно — ваш привычный Python-код. А приложения можно запускать локально или выкладывать в интернет!

Минималистичный Hello World

Начнём с самого простого примера. Создадим страницу, которая выводит “Hello, Streamlit!”:

import streamlit as st

st.title("Hello, Streamlit!")
st.write("Это наше первое интерактивное приложение!")


Сохрани файл, например, как app.py и запусти:

streamlit run app.py


Откроется браузер — и вуаля! У тебя уже есть полноценное приложение.

Добавляем интерактивность

Теперь добавим немного динамики. Представьте, что вы хотите построить график синуса — пользователь сам выбирает диапазон для оси X.

import streamlit as st
import numpy as np
import matplotlib.pyplot as plt

st.title("График синуса")
x_start = st.slider("Начало диапазона", 0, 10, 0)
x_end = st.slider("Конец диапазона", 1, 20, 10)

x = np.linspace(x_start, x_end, 100)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)
st.pyplot(fig)


Слайдеры позволяют моментально менять диапазон без перезагрузки страницы — всё происходит мгновенно!

Загрузка и обработка данных

Streamlit отлично справляется с загрузкой файлов и мгновенной обработкой данных. Например, вот способ быстро посмотреть содержимое csv-файла:

import streamlit as st
import pandas as pd

st.title("Загрузка данных")
uploaded_file = st.file_uploader("Выберите CSV-файл")

if uploaded_file is not None:
df = pd.read_csv(uploaded_file)
st.write("Первые 5 строк данных:")
st.write(df.head())


Вывод

Streamlit — инструмент, который буквально стирает границы между анализом данных и созданием готовых инструментов для пользователей. Всё максимально просто: реагируем на действия пользователя, визуализируем данные, загружаем таблицы — и всё это без боли и лишних сложностей. Попробуйте добавить Streamlit в свой инструментарий, и ваши проекты заиграют новыми красками!
👍31
- Введение в asyncio и его применение для ввода-вывода
Привет, я Иван, и сегодня мы заглянем за кулисы магического модуля Python — asyncio. Представьте, что вы пишете программу, которая скачивает десятки файлов или постоянно получает сообщения с сервера. Если подходить к задаче привычно, ваш скрипт будет то и дело “замораживаться”, ведь стандартный ввод-вывод в Python синхронен — выполняется строго по очереди.

А теперь представьте: ваши задачи будто цирковые акробаты — работают параллельно, не мешая друг другу, и без лишних пауз. Вот тут на сцену и выходит asyncio!

## Немного теории: что такое asyncio и зачем он нужен

asyncio — это стандартный модуль Python, который позволяет писать асинхронный код. В отличие от потоков и процессов, асинхронность (или кооперативная многозадачность) позволяет выполнять множество ввода-вывода задач одновременно внутри одного потока. Все это управляется так называемым “циклом событий” (event loop). Каждая задача сообщает: “я жду, можешь обработать что-нибудь еще!”.

## Пример 1: Асинхронная задержка

Посмотрим на простой пример: одновременное ожидание с помощью asyncio.sleep().

import asyncio

async def print_after_delay(text, delay):
await asyncio.sleep(delay)
print(text)

async def main():
await asyncio.gather(
print_after_delay("Hello", 2),
print_after_delay("World!", 1)
)

asyncio.run(main())

Выполнение "Hello" и "World!" не блокирует основной поток: оба задания стартуют, но результат появляется раньше для того, где задержка меньше.

## Пример 2: Асинхронный HTTP-запрос

Асинхронность особенно полезна для сетевых операций. Используем вместе с популярной библиотекой aiohttp:

import asyncio
import aiohttp

async def fetch_status(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
print(f"{url}: {response.status}")

async def main():
urls = [
"https://python.org",
"https://google.com",
"https://example.com"
]
tasks = [fetch_status(url) for url in urls]
await asyncio.gather(*tasks)

asyncio.run(main())

Здесь три запроса отправляются параллельно — экономия времени налицо!

## Подводим итоги

Ввод-вывод — частая причина “тормозов” скриптов. Asyncio позволяет эффективно запускать множество таких операций, не занимая поток ожиданием. Это мощный инструмент для современного Python — попробуйте, и ваша программа заиграет новыми красками!
👍1
- Работа с различными форматами данных: от CSV до YAML
Привет! Я Иван, и сегодня мы поговорим про работу с форматом данных в Python — от знакомого CSV до YAML. Почему это важно? Почти все программы сегодня обмениваются данными, и понимание этих форматов существенно облегчает жизнь начинающему программисту.

### Парсим CSV как профи

CSV (Comma-Separated Values) встречается повсюду: от баз данных до выгрузок из «1С». Встроенный модуль csv позволяет работать с этими файлами удобно и быстро.

import csv

with open('data.csv', mode='r', newline='') as file:
reader = csv.DictReader(file)
for row in reader:
print(row['name'], row['age'])

В этом примере DictReader возвращает строки как словари: row['name'] – и все готово!

### JSON: Дружим с вебом

JSON — король обмена данными в интернете. В Python взаимодействие с ним интуитивно понятно:

import json

data = {'name': 'Ivan', 'active': True}
with open('data.json', 'w') as file:
json.dump(data, file)

with open('data.json', 'r') as file:
output = json.load(file)
print(output['name'])

Чтение и запись почти не отличаются – используем json.dump и json.load.

### XML: Для любителей тегов

XML кажется устаревшим, но до сих пор встречается. Тут поможет xml.etree.ElementTree:

import xml.etree.ElementTree as ET

tree = ET.parse('data.xml')
root = tree.getroot()
for user in root.findall('user'):
print(user.find('login').text)


Элементы ищутся с помощью методов find и findall. Для небольших проектов чаще всего этого достаточно.

### YAML: Человечно и читаемо

YAML любят в мире DevOps и настройки сервисов за его читаемость. Для работы с YAML понадобится сторонний модуль PyYAML:

import yaml

data = {'project': 'Blog', 'contributors': ['Ivan', 'Alice']}
with open('config.yaml', 'w') as file:
yaml.dump(data, file)

with open('config.yaml') as file:
output = yaml.safe_load(file)
print(output['contributors'])

Здесь читаем и пишем почти так же просто, как с JSON.

---

Совет дня: умение “пилотировать” разные форматы данных — универсальный навык. Эти модули и простые паттерны чтения/записи пригодятся и для автоматизации, и для реальных проектов. Пройди этот путь — и данные больше не будут для тебя “черным ящиком”!
👍21