и посмотреть медиа
Код на салфетке - Python кодинг
и посмотреть медиа
Канал о программировании на Python и других языках. Простые объяснения и коды.
Канал о программировании на Python и других языках. Простые объяснения и коды.
AI бот для озвучки текста и клонирования голоса в Telegram. Создавай аудио с помощью нейросети быстро и просто.
Ресурс для интересующихся программированием. Фокус на Python, но охватывает и другие темы. Простые примеры и разборы.
Знаете ли вы, что += в Python это не просто сокращение x = x + y? Выглядит как короткая запись – но под капотом это два разных оператора. x = x + y всегда создает новый объект и присваивает его переменной слева. += сначала пытается изменить сам существующий объект, не создавая новый – через метод __iadd__. И только если у типа такого метода нет – работает как обычный +: создает новый объект. Для изменяемых типов (list, bytearray) разница принципиальна. Если на один список смотрят две переменные, две внешне одинаковые операции дают разный результат: a = [1, 2, 3] b = a a += [4] print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3, 4] – b изменился, теперь это тот же список a = [1, 2, 3] b = a a = a + [4] print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3] – новый объект, b нетронут Для списка += вызывает метод list.__iadd__ – он дописывает элементы в существующий объект и возвращает тот же самый объект. + всегда создает новый список. Поэтому когда на один список уже есть другая ссылка, результаты двух операций расходятся. Еще одна ситуация – кортеж, внутри которого лежит изменяемый объект: t = ([1, 2, 3],) try: t[0] += [4] except TypeError as e: print(e) # 'tuple' object does not support item assignment print(t) # ([1, 2, 3, 4],) – список ВНУТРИ обновился Python выполняет t[0] += [4] в два шага: сначала вызывает list.__iadd__ на внутреннем списке – список меняется и становится [1, 2, 3, 4]. Потом Python пытается записать результат обратно через t[0] = ... – и падает, потому что кортеж неизменяем. Операция и упала с ошибкой, и сработала одновременно. Понять, создает ли += новый объект или меняет старый – можно через id(): x = 10 print(id(x)) x += 1 print(id(x)) # другой id – int неизменяем, += создал новый объект lst = [1, 2] print(id(lst)) lst += [3] print(id(lst)) # тот же id – сам список поменялся, новый объект не создавался Для неизменяемых типов (int, str, tuple, frozenset) += действительно эквивалентен x = x + y – создается новый объект и присваивается переменной. Для изменяемых – меняется тот же объект, к которому уже были привязаны и другие переменные. Отсюда и расхождение ссылок, и парадокс с кортежем. += это не синтаксический сахар, а отдельный оператор со своим dunder-методом __iadd__. Для изменяемых типов он меняет сам существующий объект, не создавая новый – из-за этого ломаются разделяемые ссылки и появляется парадокс с кортежем, в котором операция падает и срабатывает одновременно. То же самое относится к -=, *=, /= и остальным – у каждого свой __isub__, __imul__, __itruediv__. В следующий вторник – * на списке: почему [[]] * 3 это не три копии, а три ссылки на один объект. Код на салфетке x Кусочки кода
Открыть канал и посмотреть медиаТолько зарегистрированные пользователи могут делиться своим мнением.
Станьте первым, кто поделится своим впечатлением об этом ресурсе!