from collections import OrderedDict
call_depth = 0
def trace(func):
def wrapper(*args, **kwargs):
global call_depth
call_depth += 1
indent = " " * call_depth
print(f"{indent}➡ {func.__name__}({', '.join(map(str, args))})")
result = func(*args, **kwargs)
print(f"{indent} {result}")
call_depth -= 1
return result
return wrapper
def lru_cache(maxsize=2):
cache = OrderedDict()
def decorator(func):
def wrapper(*args, **kwargs):
key = (args, tuple(sorted(kwargs.items())))
if key in cache:
cache.move_to_end(key)
return f"[CACHE] {cache[key]}"
result = func(*args, **kwargs)
cache[key] = result
if len(cache) > maxsize:
cache.popitem(last=False)
return f"[NEW] {result}"
return wrapper
return decorator
@lru_cache(maxsize=2)
@trace
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(4))
print(fibonacci(3))
print(fibonacci(5))
print(f"max depth: {call_depth}")
Please open Telegram to view this post
VIEW IN TELEGRAM
Встроенный в Python модуль urllib работает, но он неудобный и громоздкий. Requests делает то же самое, но в 10 раз проще и понятнее.
import requests
# 1. GET-запрос (самое частое)
response = requests.get("https://api.github.com/users/python")
print(response.status_code) # 200
print(response.json()["name"]) # Python Software Foundation
# 2. POST-запрос с данными
new_post = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json={"title": "Мой пост", "body": "Текст", "userId": 1}
)
print(new_post.status_code) # 201 (создано)
print(new_post.json()["id"]) # 101
# 3. Обработка ошибок
bad_response = requests.get("https://api.github.com/user/999999999")
if bad_response.status_code == 404:
print(“Пользователь не найден")
pip install requestsPlease open Telegram to view this post
VIEW IN TELEGRAM
❤1
В статье с нуля разбирается что такое внимание (Attention), принципы работы, и как это вообще использовать.
Please open Telegram to view this post
VIEW IN TELEGRAM
import time
history = []
def delay_printer(sec):
def decorator(func):
def wrapper(n):
time.sleep(sec)
result = func(n)
history.append(result)
return f"[D{sec}] {result}"
return wrapper
return decorator
def counter(func):
def wrapper(n):
wrapper.count += 1
result = func(n)
return f"[#{wrapper.count}] {result}"
wrapper.count = 0
return wrapper
@delay_printer(1)
@counter
def double(x):
return x * 2
@delay_printer(2)
@counter
def triple(x):
return x * 3
print(double(5))
print(triple(5))
print(double(5))
print(f"history: {history}")Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
В статье результаты тестирования pandas, openpyxl, Tablib, DuckDB, LibreOffice и даже связки с Rust. Кто справился лучше всех и как за 4 секунды Python «проглотил» полмиллиона строк.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
cached_property превращает метод в свойство, которое вычисляется один раз при первом доступе и кэшируется в экземпляре. Полезно для дорогих вычислений и ленивой инициализацииfrom functools import cached_property
import time
class Report:
def init(self, user_id):
self.user_id = user_id
@cached_property
def stats(self):
print("Вычисляю...") # выполнится только при первом доступе
time.sleep(1)
return {"orders": 42, "spent": 199.99}
r = Report(123)
print(r.stats) # первый доступ — расчёт и кэширование
print(r.stats) # последующие — мгновенно из кэша
del r.dict["stats"] # инвалидация кэша
print(r.stats) # пересчёт после инвалидации
@cached_property сохраняет результат в instance.__dict__ под именем свойства.del obj.__dict__["attr"] — значение пересчитается при следующем доступе.Please open Telegram to view this post
VIEW IN TELEGRAM
OpenAI Agents SDK — это легковесная, но мощная платформа для создания рабочих процессов с участием нескольких агентов. Она не зависит от конкретного поставщика услуг и поддерживает API OpenAI Responses и Chat Completions, а также более 100 других LLM-модулей.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
💩6❤1
def make_counter():
count = [0]
def increment():
count[0] += 1
return count[0]
def get():
return count[0]
return increment, get
inc1, get1 = make_counter()
inc2, get2 = make_counter()
inc1()
inc1()
inc2()
inc1()
print(get1(), get2())
print(inc2())
print(get1(), get2())Please open Telegram to view this post
VIEW IN TELEGRAM
💩9😁2🤮1
По умолчанию каждый экземпляр Python хранит атрибуты в словаре dict. Это удобно, но съедает много памяти.__ —для экофиксирует набор атрибутов, убираяlots__ —дли� Фишка: __sl
class Report:
— отключае= ('user_id', 'stats') # только эти атрибуты
def __init__(self, user_id):
self.user_id = user_id
self.stats = {} # теперь stats не динамический
r = Report(123)
r.new_attr = 42 # ❌ AttributeError!
— Вместо dict создаются дескрипторы для каждого атрибута из slots.
— Экземпляр хранит значения в компактном массиве, не в хэш-таблице.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔6👎5😱1
glom — декларативная библиотека для извлечения и трансформации вложенных структур данных (dict/list/tuple). Позволяет описывать «что достать и как преобразовать» короткой спецификацией вместо ручных циклов и
if.🟢 Доступ к глубоко вложенным полям без try/except🟢 Маппинг и агрегирование списков одной строкой🟢 Значения по умолчанию и безопасные обходы отсутствующих ключей🟢 Композиция спецификаций для сложных преобразований
from glom import glom, T
data = {
"user": {"name": "Alice", "age": 30, "emails": ["a@x.io", "b@y.io"]},
"orders": [{"id": 1, "total": 99.9}, {"id": 2, "total": 15.0}]
}
spec = {
"username": T["user"]["name"],
"primary_email": T["user"]["emails"][0],
"order_ids": (T["orders"], [T["id"]]),
"sum_total": (T["orders"], sum, [T["total"]]), # суммируем totals
}
print(glom(data, spec))
# ➔ {'username': 'Alice', 'primary_email': 'a@x.io', 'order_ids': [1, 2], 'sum_total': 114.9}
# Безопасный доступ с дефолтом:
print(glom(data, "user.phone", default="no phone")) # ➔ 'no phone'
pip install glom
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2