и посмотреть медиа
Code on a Napkin - Python coding
и посмотреть медиа
Channel about programming in Python and other languages. Simple explanations and codes.
Channel about programming in Python and other languages. Simple explanations and codes.
AI bot for text-to-speech and voice cloning in Telegram. Create audio using neural network quickly and easily.
Resource for those interested in programming. Focus on Python, but covers other topics as well. Simple examples and breakdowns.
Знаете ли вы, что += в 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 Кусочки кода
Открыть канал и посмотреть медиаOnly registered users can share their opinion.
Be the first to share your impression of this resource!