🐍 Укус питона 🐍
2.45K subscribers
1.07K photos
26 videos
285 links
🐍 Канал о программировании на языке Python. Тематические уроки и лайфхаки.

👽 Админ - @it_dashka
🔊 Купить рекламу: https://telega.in/c/byteofpython

👉 Чат: @abyteofpython
👉 Поделиться с друзьями: @byteofpython
Download Telegram
Что выведет код?

class A:
def __eq__(self, o): return isinstance(o, A)

class B:
def __eq__(self, o): return isinstance(o, B)
__hash__ = object.__hash__

s = set()
try:
s.add(A())
except TypeError:
print("A")
b = B()
s.add(b)
print("B", b in s)
👩‍💻 Протокол итерации — как работает цикл for под капотом

В Python любой объект можно сделать итерируемым, если он реализует протокол итерации — методы __iter__() и __next__().

Это основа работы for, генераторов, списковых включений и даже файлов


➡️ Пример:

class Counter:
def __init__(self, limit):
self.limit = limit
self.value = 0

def __iter__(self):
return self

def __next__(self):
if self.value < self.limit:
self.value += 1
return self.value
raise StopIteration

for i in Counter(3):
print(i)
# 1 2 3


📌 Цикл for просто вызывает next() до тех пор, пока не появится StopIteration.
Please open Telegram to view this post
VIEW IN TELEGRAM
👩‍💻 Протокол дескрипторов — скрытый механизм свойств и ORM

В Python за @property, staticmethod, classmethod и даже ORM-поля стоит единый механизм — дескрипторы.

Это объекты, которые управляют доступом к атрибутам через методы __get__, __set__, __delete__


➡️ Пример:

class LoggedAttribute:
def __init__(self, name):
self.name = name

def __get__(self, instance, owner):
value = instance.__dict__.get(self.name)
print(f"Получено {self.name} = {value}")
return value

def __set__(self, instance, value):
print(f"Изменено {self.name} = {value}")
instance.__dict__[self.name] = value


class User:
age = LoggedAttribute("age")


u = User()
u.age = 30
print(u.age)


📌 При обращении к u.age срабатывают методы дескриптора, а не прямой доступ к атрибуту.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет код?

import itertools

lst = [[1, 2], [3]]
it = itertools.chain.from_iterable(lst)
print(next(it))
lst.append([4, 5])
print(list(it))
👩‍💻 WeakRef — как избежать утечек памяти в Python

Иногда объект больше не нужен, но на него всё ещё ссылаются другие части программы. Обычная ссылка удерживает объект в памяти, а слабая ссылка (weak reference) — нет.

Она не мешает сборщику мусора удалить объект, если больше нет сильных ссылок


➡️ Пример:

import weakref

class Data:
def __init__(self, name):
self.name = name
def __del__(self):
print(f"{self.name} удалён")

obj = Data("Test")
ref = weakref.ref(obj)

print(ref()) # <__main__.Data object at ...>

del obj
print(ref()) # None — объект собран GC


📌 weakref.ref() создаёт слабую ссылку: объект может быть удалён, даже если ссылка ещё существует.
Please open Telegram to view this post
VIEW IN TELEGRAM
👩‍💻 Контракты через аннотации — не просто подсказки типов

Аннотации типов (type hints) — это не только помощь IDE.
С их помощью можно внедрять контроль логики исполнения — проверять типы, значения и инварианты прямо во время работы программы.

➡️ Пример:

from typing import get_type_hints

def enforce_types(func):
hints = get_type_hints(func)
def wrapper(*args, **kwargs):
for name, arg in zip(hints, args):
if not isinstance(arg, hints[name]):
raise TypeError(f"{name} должен быть {hints[name].__name__}")
return func(*args, **kwargs)
return wrapper

@enforce_types
def greet(name: str, age: int):
print(f"{name}, {age}")

greet("Анна", 25) #
greet("Анна", "25") # TypeError


📌 Здесь аннотации становятся частью исполняемого контракта, а не просто документацией.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет код?

x = 0

def outer():
x = 1
def inner():
nonlocal x
x += 1
return x
print("A", inner(), x)
x = 5
print("B", inner(), x)

outer()
print("G", x)
👩‍💻 Динамическое создание классов — метапрограммирование в чистом виде

В Python классы — это тоже объекты, и их можно создавать "на лету" с помощью функции type(). Это открывает путь к динамическому API, автоматическим моделям и DSL.

➡️ Пример:

def make_model(name, **fields):
return type(name, (object,), fields)

User = make_model("User", name="Анна", age=25)
print(User.name) # Анна

admin = User()
admin.role = "admin"
print(admin.role) # admin


📌 Здесь type() создаёт новый класс User прямо во время исполнения.
Please open Telegram to view this post
VIEW IN TELEGRAM