Программистика
Closed channel
Лучший канал про python Ссылка для друга: https://t.me/+Ai6ughKtf5g2ZmFi Купить рекламу: https://telega.in/c/+Ai6ughKtf5g2ZmFi Админ: @JeyRahol По рекламе: @ReivuManager
Show more5 574
Subscribers
-324 hours
+67 days
+4930 days
Posts Archive
5 572
📁 `pathlib` вместо `os.path`: работай с путями по-человечески
Устали от
os.path.join(os.path.dirname(__file__), 'data', 'file.txt')? В Python есть современный объектно-ориентированный способ.
❌ Старый стиль (os.path):
import os
path = os.path.join(os.path.dirname(__file__), 'data', 'file.txt')
✔️ Новый стиль (pathlib):
from pathlib import Path
path = Path(__file__).parent / 'data' / 'file.txt'
🟢 Что умеет pathlib:
- Path.cwd() — текущая директория
- Path.home() — домашняя папка
- path.exists(), path.is_file(), path.is_dir()
- path.read_text(), path.write_text('content')
- path.glob('*.py') — поиск файлов
- path.resolve() — абсолютный путь
- path.with_suffix('.txt') — замена расширения
# Чтение и запись одной строкой
content = Path('config.json').read_text()
Path('output.txt').write_text('Hello, world!')
pathlib — это не просто синтаксический сахар, а удобный инструмент, который делает код чище и кроссплатформенным.
Программистика|| #tips5 572
🔠 Слили 4 ТБ по IT, хакингу и разработке.
⚪️ Все лучшие инструкции, гайды, книги и инструменты — без воды.
🖥 Курсы & GitHub — 579GB
☁️ Хакинг & ИБ — 756GB
🤒 OSINT — 315GB
⌨️ Python — 955GB
🙃 Linux & Bash — 459GB
😦 Работа в IT — 278GB
🖥 Общий архив — 946GB
➡️ Присоединяйтесь и скачивайте.
Пост будет удален через 48 часов.
5 572
🔌 Niquests: HTTP-клиент, который сделал Requests устаревшим (и работает в 2-3 раза быстрее)
Если вы всё ещё используете
requests — вы отстаёте от жизни. Requests официально заморожен и не получает новых фич. На сцену вышел Niquests — его прямой наследник, который работает быстрее, поддерживает HTTP/2 и HTTP/3 «из коробки» и при этом полностью совместим с кодом, написанным под requests.
Главное преимущество Niquests — он просто работает. Меняете import requests на import niquests as requests — и всё. Все ваши старые скрипты с requests.get(), Session(), hooks и mock-библиотеками продолжают работать без изменений. При этом Niquests автоматически включает HTTP/2 и HTTP/3, поддерживает асинхронность, потокобезопасность и даже DNSSEC.
📦 Установка:
pip install niquests
🚀 Пример (ваш старый код — просто работает):
# Было (requests)
import requests
response = requests.get("https://httpbingo.org/get")
print(response.json())
# Стало (Niquests) — просто меняете импорт
import niquests as requests
response = requests.get("https://httpbingo.org/get")
print(response.json()) # Всё работает, но уже через HTTP/2!
Асинхронный пример:
import niquests
async def fetch():
async with niquests.AsyncSession() as session:
response = await session.get("https://api.example.com/data")
return response.json()
Программистика || #Репозиторий5 572
Самый прогерский канал, где за 10 минут ты научишься:
/ Пр0бuв по фото и номеру в ТГ
// Как взломать вебку подруги
/// Мануал по OSINT разведке
Ссылка действительна
23 ч. 59 мин. 👇
https://t.me/+3xWtEj_0qa9hNmUy
5 572
🧩 Генераторы: `yield` и `yield from` — как это работает под капотом и зачем это нужно
Вы каждый день пишете
for x in range(10), но задумывались ли вы, как range выдаёт числа по одному, не создавая список? Или как работают бесконечные последовательности? Генераторы — одна из самых мощных фич Python, которую многие используют, но не до конца понимают. Разбираемся, что скрывается за yield.
🧱 Проблема: список vs генератор
Когда вы создаёте список, все элементы хранятся в памяти. Для миллиона чисел это 8 МБ только на ссылки, не считая самих объектов. Генератор вычисляет значения по требованию — экономия памяти очевидна.
❌ Список (память):
squares = [x**2 for x in range(10_000_000)] # ~80 МБ
✔️ Генератор (экономия):
squares = (x**2 for x in range(10_000_000)) # ~0 байт
Но генераторы — это не только экономия памяти. Это ещё и управление выполнением, и асинхронность, и бесконечные последовательности.
🧠 Как работает `yield` под капотом
Когда Python встречает yield, функция превращается в генератор. При вызове она не выполняется, а возвращает объект-генератор. При первом next() выполняется до первого yield, возвращает значение и приостанавливается. При следующем next() возобновляется с того же места.
def simple_gen():
print("Начало")
yield 1
print("Продолжение")
yield 2
print("Конец")
g = simple_gen()
print(next(g)) # Начало → 1
print(next(g)) # Продолжение → 2
print(next(g)) # Конец → StopIteration
Внутри генератор хранит состояние: локальные переменные, текущую позицию, стек вызовов. Это похоже на сопрограмму.
🔁 `yield from` — делегирование другому генератору
До Python 3.3, чтобы передать управление вложенному генератору, приходилось писать циклы. yield from делает это автоматически.
❌ Без `yield from` (муторно):
def flatten(nested):
for sublist in nested:
for item in sublist:
yield item
✔️ С `yield from` (красиво):
def flatten(nested):
for sublist in nested:
yield from sublist
yield from не только передаёт значения, но и принимает send() и throw() от вызывающего, что делает генераторы полноценными сопрограммами.
Пример с `yield from` в цепочке:
def chain(*iterables):
for it in iterables:
yield from it
for x in chain([1, 2], "abc", range(3)):
print(x) # 1, 2, a, b, c, 0, 1, 2
🧪 Генераторы как сопрограммы (двусторонняя связь)
Генераторы могут не только выдавать значения, но и принимать их извне через send(). Это превращает их в сопрограммы.
def grep(pattern):
print(f"Ищу {pattern}")
while True:
line = yield
if pattern in line:
print(f"Найдено: {line}")
g = grep("python")
next(g) # активация
g.send("Java рулит") # ничего
g.send("Python рулит") # Найдено: Python рулит
g.close()
Аналог send для throw — пробросить исключение внутрь генератора.
Пример пайплайна с генераторами:
def read_lines(filename):
with open(filename) as f:
for line in f:
yield line
def filter_errors(lines):
for line in lines:
if "ERROR" in line:
yield line
def extract_message(line):
yield line.split(":")[-1].strip()
pipeline = extract_message(filter_errors(read_lines("app.log")))
for msg in pipeline:
print(msg)
Каждый шаг обрабатывает данные лениво, без промежуточных списков.
💡 Запомни:
🟢 Генератор — это функция с yield, возвращающая итератор, который вычисляет значения по требованию. 🟢 yield from делегирует выполнение другому генератору, упрощая вложенность. 🟢 Генераторы экономят память и позволяют обрабатывать бесконечные последовательности. 🟢 send() и throw() делают генераторы полноценными сопрограммами. 🟢 В Python 3.5+ async/await заменили генераторы для асинхронности, но генераторы остались незаменимы для ленивых вычислений.Программистика || #Статья
5 572
Самый прогерский канал, где за 10 минут ты научишься:
/ Пр0бuв по фото и номеру в ТГ
// Как взломать вебку подруги
/// Мануал по OSINT разведке
Ссылка действительна
23 ч. 59 мин. 👇
https://t.me/+21aDomQkVOMxMjU6
5 572
🖥 simplejson — это библиотека для Python, обеспечивающая простое, быстрое и расширяемое кодирование и декодирование JSON! 🟢 Она полностью написана на Python и не имеет внешних зависимостей, но включает необязательное C-расширение для повышения производительности. 🟢Поддерживает Python версии 3.3 и выше, а также имеет обратную совместимость с Python 2.5+.Программистика||#Репозиторий
5 572
Байесовская оптимизация с примерами из библиотек Python
Книга рассказывает об оптимизации моделей машинного обучения на основе байесовского метода и теории вероятностей. Примеры составлены на языке Python с использованием библиотек PyTorch, GPyTorch и BoTorch. Описаны приемы настройки гиперпараметров, гауссовское распределение, использование политик машинного обучения, в частности на основе задачи о многоруких бандитах, повышение производительности вычислений, многовариантная оптимизация с учетом полезности и затрат, а также применение байесовского метода в специализированных сценариях.Программистика||#doc
5 572
Опа, тут бывший сеньор одного из IT-отделов Яндекса Игорь Никитин выкатил целый канал про Python — и это лучшее, что есть в рунете по теме.
Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.
Хватит душить питона, учись его кодить: https://t.me/+evJ7pToYSEIwOGZi 🐍
5 572
Продуктовый Python — Инженерия
Третий курс серии «Продуктовый Python» — о том, как писать надёжный код, работать с базами данных, символьными формулами и валидацией данных, используя лучшие библиотеки Python. Курс знакомит с инструментами, о которых аналитики часто забывают или не знают: типизация, SQLModel, SymPy, Pydantic. Вместо изобретения велосипедов — готовые, оптимизированные и проверенные решения.
🌐 СсылкаПрограммистика || #Course
5 572
🔥Стажировки и вакансии для IT специалистов
- Вакансии которых нет на джоб-агрегаторах
- Только прямые контакты HR в Telegram
🤖 ML & DS 👩💻 DevOps
👨✈️ ИБ & OSINT 👣 Go
👩💻 Mobile 👩💻 C#
👩💻 Node.js 👩💻 Python
🔎 QA 👩💻 Java
👩💻 UX/UI 👩💻 Frontend
🖼️ PHP 📋 Analyst
💼 1C 🖥 SQL
👩💻 IT HR
Пока другие листают джоб-сайты — ты уже пишешь HR в Telegram.
5 572
💻 Вопрос с собеседования: Что такое перегрузка операторов и как она работает в Python?
Это вопрос для middle и senior уровня. Многие знают, что можно перегрузить
+ через __add__, но не понимают, как работает вся система. На собеседовании проверяют, знаете ли вы магические методы и можете ли написать класс, который ведёт себя как встроенный тип.
📌 Базовый ответ (которого ждут от джуна):
Перегрузка операторов — это возможность определить поведение операторов (+, -, *, ==, < и т.д.) для пользовательских классов через специальные методы (магические методы). Например, __add__ определяет поведение +.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2 # Vector(4, 6)
🧱 Глубокий разбор (для мидла и сеньора):
2. Реверсивные операции
Если левый операнд не поддерживает операцию, Python вызывает метод правого операнда с r (например, __radd__).
class Number:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Number(self.value + other.value)
def __radd__(self, other):
return Number(other.value + self.value)
a = Number(5)
b = Number(3)
c = 10 + a # Вызовет __radd__ у Number (10 + a)
3. `functools.total_ordering` — автоматические сравнения
Если определить __eq__ и один из методов сравнения, декоратор @total_ordering сгенерирует остальные.
from functools import total_ordering
@total_ordering
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
def __lt__(self, other):
return self.age < other.age
# __le__, __gt__, __ge__ генерируются автоматически
p1 = Person("Алиса", 30)
p2 = Person("Боб", 25)
print(p1 > p2) # True (автоматически)
4. Пример полноценного класса с перегрузкой
class Money:
def __init__(self, amount, currency="USD"):
self.amount = amount
self.currency = currency
def __add__(self, other):
if self.currency != other.currency:
raise ValueError("Разные валюты")
return Money(self.amount + other.amount, self.currency)
def __sub__(self, other):
if self.currency != other.currency:
raise ValueError("Разные валюты")
return Money(self.amount - other.amount, self.currency)
def __mul__(self, factor):
return Money(self.amount * factor, self.currency)
def __eq__(self, other):
return self.amount == other.amount and self.currency == other.currency
def __lt__(self, other):
if self.currency != other.currency:
raise ValueError("Разные валюты")
return self.amount < other.amount
def __repr__(self):
return f"{self.amount} {self.currency}"
m1 = Money(100, "USD")
m2 = Money(50, "USD")
print(m1 + m2) # 150 USD
print(m1 * 2) # 200 USD
print(m1 > m2) # True
⚠️ Ловушки и частые ошибки
1. Забыть про `__radd__` — при сложении с числом слева (например, 10 + obj) может не работать.
2. Не проверять типы — __add__ должен проверять, что other — правильного типа.
3. Перегрузка `==` без перегрузки `!=` — != автоматически инвертирует ==, но только если определён __ne__ или Python 3.8+.
4. Сложные сравнения без `@total_ordering` — если определить только __lt__ и __eq__, остальные сравнения не будут работать.
5. Изменяемость и мутация — арифметические операции должны возвращать новый объект, а не изменять существующий.
💡 Итоговый ответ для собеседования:
1. Перегрузка операторов — это определение поведения операторов через магические методы.
2. Основные методы: __add__, __sub__, __mul__, __truediv__, __eq__, __lt__ и т.д.
3. Реверсивные операции (__radd__) важны для поддержки операций с разными типами.
4. @total_ordering генерирует все сравнения по одному-двум методам.
5. Всегда проверяйте типы в __add__ и подобных методах.
6. Арифметические операции должны возвращать новые объекты (immutable).
Программистика|| #jobs5 572
Для тех кто просил, канал с мемами для программистов и айтишников 👇
https://t.me/+p4jLz_2jfKY0ZGYy
5 572
🖥 python-genai — это официальный SDK на Python от Google, предназначенный для интеграции генеративных моделей Google AI в приложения! 💡 Основные возможности включают генерацию текста, настройку моделей с помощью системных инструкций, параметры генерации (например, температуры, длины вывода), а также встроенные механизмы безопасности. SDK поддерживает удобную работу с параметрами через словари или модели Pydantic. Также предусмотрена интеграция с пользовательскими функциями для обработки результатов или вызова API.Программистика||#Репозиторий
5 572
🧠 Отгадка: что выведет этот код?
def create_counter():
count = 0
def inner():
nonlocal count
count += 1
return count
return inner
counters = [create_counter() for _ in range(3)]
results = [counter() for counter in counters]
print(results)
✅ Правильный ответ: 1. `[1, 1, 1]`
📖 Почему так происходит?
- Функция create_counter при каждом вызове создаёт новую локальную переменную `count` и новое замыкание inner, которое захватывает эту конкретную переменную.
- В списковом включении [create_counter() for _ in range(3)] функция вызывается три раза, поэтому создаются три независимых счётчика, каждый со своим собственным count = 0.
- Затем [counter() for counter in counters] вызывает каждую из трёх функций. Каждая увеличивает свой count с 0 до 1 и возвращает 1.
- В результате получаем [1, 1, 1].
Если бы мы создали один счётчик и вызывали его трижды — получили бы [1, 2, 3]. Но здесь три разных счётчика, поэтому каждый выдаёт 1.
Ключевой момент: create_counter возвращает новую функцию с новым замыканием при каждом вызове.
Ставьте 🔥, если было полезно!
Программистика || #quiz