PytStart | Программирование на Python
4.27K subscribers
23 photos
26 videos
57 links
Python: примеры кода, уроки, статьи

Купить рекламу: https://telega.in/c/pytstart

✍️По всем вопросам: @Pascal4eg
Download Telegram
🚰 Стриминг больших данных через генераторы и yield from

Когда данных слишком много — миллионы строк в файле, бесконечные события или поток логов — держать всё в памяти нельзя. Тут спасают генераторы и ключевое слово yield from, позволяющее строить цепочки ленивых итераторов.

📦 Чтение файла построчно
def read_file(path):
with open(path, "r") as f:
for line in f:
yield line.strip()

for row in read_file("bigdata.txt"):
print(row)

➡️ Память не переполняется: читается и отдаётся по строке.

🔗 Комбинация генераторов через yield from
def numbers():
yield from range(5)
yield from range(10, 15)

print(list(numbers()))

➡️ yield from разворачивает подгенераторы и прокидывает их значения наружу.

⚡️ Обработка пайплайнами
def read_lines(path):
with open(path) as f:
yield from f

def filter_errors(lines):
for line in lines:
if "ERROR" in line:
yield line

errors = filter_errors(read_lines("app.log"))
for e in errors:
print(e)

➡️ Логика разбивается на звенья, и каждое обрабатывает поток данных лениво.

🌀 Бесконечные источники

import time

def ticker():
while True:
yield time.time()
time.sleep(1)

for t in ticker():
print(t)

➡️ Генератор выдаёт значения бесконечно, но потребитель сам решает, когда остановиться.

📑 Вложенные пайплайны с yield from
def split_words(lines):
for line in lines:
yield from line.split()

data = ["hello world", "big data stream"]
for word in split_words(data):
print(word)

➡️ yield from красиво разрывает вложенные итерации без двойных циклов.

🚀 Генераторы + итераторы стандартной библиотеки
from itertools import islice

def stream():
for i in range(1000000):
yield i

print(list(islice(stream(), 5)))

➡️ Вместо списка в миллион чисел получаешь поток, из которого берёшь только нужное.

🗣️ Запомни: генераторы — это ленивые конвейеры данных, yield from связывает их в цепочку. Такой подход позволяет обрабатывать гигабайты без переполнения памяти и писать код, который дышит как поток.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
👩‍💻 DSL в Python через __call__ и __getitem__ — красиво, читаемо, Pythonic

Хочешь, чтобы твой код выглядел как язык сам по себе?
Python позволяет строить мини-языки внутри кода — без библиотек, просто на магии dunder-методов.

✔️ Начнём с __call__

Он делает объект вызываемым, как функцию:
class Hello:
def __call__(self, name):
return f"Привет, {name}!"

h = Hello()
print(h("Мир")) # Привет, Мир!

Полезно, когда хочется сделать объекты лаконичными. Можно даже прокидывать параметры как в обычной функции.

✔️ Теперь __getitem__

Позволяет обращаться к объекту через квадратные скобки:
class SecretBox:
def __getitem__(self, key):
return f"🔒 Внутри: {key}"

box = SecretBox()
print(box["password"]) # 🔒 Внутри: password

Ты можешь использовать это для красивого синтаксиса без точек и скобок.

🤝 Комбинируем в DSL
class SQL:
def __call__(self, table):
return f"SELECT * FROM {table}"

def __getitem__(self, field):
return f'"{field}"'

q = SQL()

print(q("users")) # SELECT * FROM users
print(q["email"]) # "email"

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

🧪 Более мощный пример: API-доступ
class API:
def __init__(self, base):
self.base = base

def __getitem__(self, endpoint):
return f"{self.base}/{endpoint}"

def __call__(self, endpoint, **params):
query = "&".join(f"{k}={v}" for k, v in params.items())
return f"{self.base}/{endpoint}?{query}"

api = API("https://api.server")

print(api["users"]) # https://api.server/users
print(api("users", id=5, active=True)) # https://api.server/users?id=5&active=True

Такой подход часто используют в клиентах к REST API, чтобы код выглядел как естественный DSL.

🧰 А можно вообще без классов?
class K:
def __getitem__(self, key):
return lambda d: d.get(key)

k = K()
data = {"name": "Neo", "role": "Hacker"}

print(k["name"](data)) # Neo
print(k["role"](data)) # Hacker

Так строятся мини-функции доступа к полям. Особенно круто в map/filter.

🗣️ Запомни: __call__ и __getitem__ — это способ превратить скучные объекты в выразительный синтаксис. Так строятся мини-языки прямо в Python: понятные, компактные и без лишнего шума.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
⚡️ functools.cache вместо самодельного мемо — просто и эффективно

Зачем писать свои кеши, если Python уже умеет это из коробки?
С версии 3.9 появился @cache — аналог lru_cache, но проще и быстрее, если тебе не нужен лимит.

Было так (ручной мемо):
_cache = {}

def fib(n):
if n in _cache:
return _cache[n]
if n <= 1:
return n
_cache[n] = fib(n-1) + fib(n-2)
return _cache[n]

🧠 Работает, но нужно писать проверку, хранить словарь, вручную всё продумывать.

🔄 А теперь просто:
from functools import cache

@cache
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)

👏 Всё! Автоматически кеширует, ничего лишнего не пишем.

📌 Отличия от @lru_cache
from functools import lru_cache, cache

🟢 @lru_cache: можно задать размер (maxsize), есть контроль
🟢 @cache: просто бесконечный кеш всех входов → выходов

Если не нужна "очистка", бери @cache — он быстрее и проще.

🧪 Пример с реальным использованием:
from functools import cache
import requests

@cache
def get_user_info(user_id):
print("Запрос к API...")
return requests.get(f"https://api.example.com/users/{user_id}").json()

get_user_info(42) # Выполнит запрос
get_user_info(42) # Возьмёт из кеша


➡️ Отлично для API, парсинга, тяжёлых вычислений.

🗣️ Запомни: @functools.cache — это твой встроенный кеш без лишнего кода.
Хорош для любых чистых функций, где важна скорость и повторяемость.
Не изобретай велосипед — используй cache.
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3
👩‍💻 Антипаттерны в Python-коде, которые встречаются даже у опытных

Даже опытные разработчики пишут код, который потом сложно читать, отлаживать и сопровождать. Вот 5 антипаттернов, которые встречаются особенно часто — и что с ними делать.

1. Мутируемые значения по умолчанию
def append_item(item, items=[]):
items.append(item)
return items


Ошибка — items сохраняет состояние между вызовами. Итог — неожиданные данные.

Правильно:
def append_item(item, items=None):
if items is None:
items = []
items.append(item)
return items


2. Импорт всего (`from module import *`)

Так ты теряешь контроль над namespace и рискуешь конфликтами имён. Особенно опасно в больших проектах.

Лучше явно:
from math import sqrt, pi


3. Голый `except:`
try:
do_something()
except:
pass


Так можно «поймать» даже KeyboardInterrupt, и программа зависнет.

✔️ Лучше:
try:
do_something()
except ValueError:
handle()


4. Чрезмерно вложенные list comprehensions

[x for x in lst if x > 0 if x < 100 if x % 2 == 0]


Читаемость? Нулевая.

Явный цикл:
result = []
for x in lst:
if 0 < x < 100 and x % 2 == 0:
result.append(x)


5. Копирование ссылок на изменяемые объекты
data = [{}] * 3
data[0]["a"] = 1
print(data)


Ожидаешь три разных словаря? А получил три ссылки на один и тот же.

Делай так:
data = [{} for _ in range(3)]


🗣️ Запомни: даже если код "работает", это не значит, что он хорош. Следи за чистотой — антипаттерны незаметны, но со временем превращают проект в хаос.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
🖥 Как отсортировать список словарей по определенному полю?

Метод списка .sort() и встроенная функция sorted() принимают параметр key. Им должен быть вызываемый объект, который принимает очередной элемент (в нашем случае словарь) и возвращает значение-критерий сортировки.

Код ниже показывает, как отсортировать список людей по возрасту:

users = [{'age': 30}, {'age': 20}, {'age': 10}]
users.sort(key=lambda user: user['age'])
>>> [{'age': 10}, {'age': 20}, {'age': 30}]
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
👩‍💻 *args и **kwargs: гибкие параметры без боли

Иногда ты не знаешь заранее, сколько аргументов получит твоя функция. Python даёт тебе две магические конструкции для таких случаев — *args и **kwargs.

📌*args собирает все позиционные аргументы в кортеж:

def add_all(*args):
return sum(args)

add_all(1, 2, 3) # ➡️ 6


📌 **kwargs собирает все именованные аргументы в словарь:

def print_config(**kwargs):
for k, v in kwargs.items():
print(f"{k} = {v}")

print_config(debug=True, timeout=10)
# ➡️ debug = True
# ➡️ timeout = 10


🔥Комбинируем всё:

def func(a, b, *args, **kwargs):
pass

➡️ a и b — обязательные, args — остальные позиционные, kwargs — именованные.

🧠 Применения:

1. Проксирование аргументов
Ты вызываешь другую функцию, не зная её сигнатуру:

   def wrapper(*args, **kwargs):
return real_func(*args, **kwargs)


2. Гибкий API без переписывания сигнатур

Вместо:
   def create_user(name, email, age, is_admin=False):
...


Можно:
   def create_user(**kwargs):
...


3. Расширение без поломки интерфейса

У тебя есть базовый метод:

   def process(data, **kwargs):
...


➡️ В будущем можно спокойно добавить флаги, не меняя вызовы.


🗣️ Запомни: *args и **kwargs — это про гибкость и масштабируемость. Главное — использовать их осознанно: когда действительно нужно, а не “на всякий случай”.

📍Где применяется:
Декораторы, middleware, логгеры, фреймворки (Django, Flask), адаптеры, кастомные API, генераторы CLI-интерфейсов.
Please open Telegram to view this post
VIEW IN TELEGRAM
2💯1
👩‍💻 Как работает collections.Counter?

Counter — это удобный инструмент для подсчета элементов в коллекции.
Не обязательно писать цикл и вручную считать каждый элемент 👇

➡️ Пример:


from collections import Counter

data = "aabbbcccc"
counter = Counter(data)
print(counter) # Counter({'c': 4, 'b': 3, 'a': 2})


✔️ Можно использовать для нахождения самых частых элементов:


print(counter.most_common(2)) # [('c', 4), ('b', 3)]


⚙️ Также работает со списками:


words = ["apple", "banana", "apple", "orange", "banana", "banana"]
print(Counter(words)) # {'banana': 3, 'apple': 2, 'orange': 1}


🔥 Counter особенно полезен для:
— анализа текста
— подсчёта слов
— статистики
— обработки данных
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
🖥 Как повторить строку несколько раз

В Python для этого не нужен цикл 👇


text = "Python! "

print(text * 3)


👉 Результат:

Python! Python! Python!


💡 То же самое работает со списками:

nums = [1, 2]

print(nums * 3)


Получим:

[1, 2, 1, 2, 1, 2]


🔥 Это удобно, когда нужно быстро создать повторяющуюся строку или последовательность.

⚠️ Но со списками есть нюанс: элементы не копируются глубоко - для вложенных изменяемых объектов это может привести к неожиданному поведению.
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
🖥 Как превратить текст в речь с помощью Python

Можно заставить Python буквально говорить 🔊

Для этого есть библиотека pyttsx3:

import pyttsx3

engine = pyttsx3.init()

engine.say("Привет! Я говорю с помощью Python")
engine.runAndWait()


📦 Установка:

pip install pyttsx3


💡 Можно сделать функцию:

def speak(text):
engine.say(text)
engine.runAndWait()

speak("Сегодня изучаем Python!")


🔥 На этой основе можно сделать:
— голосового помощника
— программу для чтения текста
— озвучку уведомлений
— простого desktop-бота

И всё это — без сложных моделей и API 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍2
🖥 Как превратить PDF в текст с помощью Python

Нужно быстро достать текст из PDF? Можно автоматизировать это 👇


import fitz

doc = fitz.open("document.pdf")

for page in doc:
print(page.get_text())


📦 Установка:


pip install pymupdf


💡 А если нужно сохранить весь текст в файл:


with open("result.txt", "w", encoding="utf-8") as file:
for page in doc:
file.write(page.get_text())


🔥 Получается простой конвертер PDF → TXT.

На этом можно построить:
— поиск по документам
— обработку большого количества PDF
— извлечение данных из отчётов
— подготовку текста для AI

⚠️ Если PDF состоит из сканов, обычное извлечение текста может не сработать - тогда понадобится OCR.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
🖥 Как найти дубликаты в папке с помощью Python

Например, в папке лежат сотни файлов, и нужно понять, какие из них полностью одинаковые.

Можно сравнивать их по хэшу 👇


from pathlib import Path
import hashlib

def get_hash(path):
return hashlib.md5(path.read_bytes()).hexdigest()

files = {}

for file in Path("files").iterdir():
if file.is_file():
file_hash = get_hash(file)
files.setdefault(file_hash, []).append(file)

for group in files.values():
if len(group) > 1:
print("Дубликаты:")
for file in group:
print(" ", file)


💡 Идея простая:

📄 файл → 🔢 хэш → 🔍 сравниваем хэши

Если хэши совпали, файлы с высокой вероятностью одинаковые.

🔥 Такой скрипт можно использовать для:
— очистки папок
— поиска повторяющихся фото
— анализа больших архивов
— автоматизации работы с файлами
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
«Освоение модульного тестирования с использованием Pytest» курс на Stepik

Сегодня умение писать тесты ценится почти так же, как и умение писать сам код. Если pytest, fixtures, CI/CD и coverage всё ещё вызывают вопросы самое время это исправить

Программа курса:

• Pytest: от базовых тестов до CI/CD
• fixtures, mocking, parametrization
• Flask/API testing
• Selenium и UI тестирование
• Docker + Docker Compose
• GitHub Actions
• coverage и отчёты
• debugging и refactoring тестов

Курс построен вокруг практики: много примеров, готовых кейсов и разборов рабочих сценариев

48 часов действует скидка 25%

↗️ Пройти курс на Stepik
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🖥 Как сделать генератор случайных паролей на Python

Небольшой скрипт, который создаёт случайный пароль заданной длины 🔐


import secrets
import string

chars = string.ascii_letters + string.digits + "!@#$%^&*"

password = "".join(
secrets.choice(chars)
for _ in range(16)
)

print(password)


💡 Почему secrets, а не обычный random?

secrets предназначен именно для случаев, где важна непредсказуемость случайных значений.

📌 Можно менять длину:


length = 24

password = "".join(
secrets.choice(chars)
for _ in range(length)
)


🔥 На основе этого можно сделать:
— генератор паролей
— CLI-утилиту
— генератор токенов
— автоматическое создание временных ключей
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
Программирование c нуля «От новичка к уверенности в коде на Python»

На Stepik запустили курс для новичков, которым важно не зубрить команды, а понимать логику. Наглядные схемы и визуальные разборы показывают, что происходит внутри программы и как она работает

Много практики, понятные объяснения решений не дадут застрять на теории. Материал предлагает вам не иллюзию знаний, а ощущение контроля: вы ясно видите как из нескольких строк кода рождается работающая программа

Программа курса:

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

Эти знания фундамент для написания простых ботов и автоматизации задач

🔗Скидка 25% действует 48 часов
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21
🖥 Как автоматически отправить email с Python

Можно отправлять письма прямо из Python — например, уведомления об ошибках или отчёты 📩


import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "Отчёт"
msg["From"] = "you@example.com"
msg["To"] = "user@example.com"
msg.set_content("Отчёт готов!")

with smtplib.SMTP_SSL("smtp.example.com", 465) as smtp:
smtp.login("you@example.com", "PASSWORD")
smtp.send_message(msg)


💡 Что здесь происходит:

📨 EmailMessage — создаёт письмо
🔐 login() — авторизация на SMTP-сервере
🚀 send_message() — отправляет письмо

🔥 На этом можно сделать:
— автоматические отчёты
— уведомления о сбоях
— отправку файлов
— ежедневные рассылки

⚠️ Пароль лучше не хранить прямо в коде — используй переменные окружения или секреты.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
🔍Тестовое собеседование на Middle Python с разработчиком из Авито завтра вечером

Уже завтра вечером в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.

Как это будет:
📂 Даня, старший разработчик в Авито, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Даня будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Дане

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Python-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🖥 Как запустить несколько задач одновременно в Python

Если есть несколько задач, которые ждут сеть или другие внешние операции, можно выполнять их конкурентно с asyncio


import asyncio

async def task(name, delay):
await asyncio.sleep(delay)
print(f"{name} готова")

async def main():
await asyncio.gather(
task("Задача 1", 2),
task("Задача 2", 1),
task("Задача 3", 3),
)

asyncio.run(main())


💡 Здесь три задачи запускаются конкурентно.

⏱️ Вместо ожидания примерно 2 + 1 + 3 = 6 секунд программа закончит примерно за 3 секунды - по времени самой долгой задачи.

🔥 Особенно полезно для:
— запросов к API
— загрузки данных
— сетевых приложений
— Telegram-ботов

⚠️ asyncio не делает обычные CPU-вычисления быстрее — он особенно хорош для задач, где много ожидания.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21