- 1
- 2
- 3
- 4
- 5
- 6
def f(l = []):
l.append(len(l))
return l
f()
f()
print f()
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−94
def f(l = []):
l.append(len(l))
return l
f()
f()
print f()
Есть мнения что выведет?
http://ideone.com/Q6Oc2I
Иди на хуй, еболдыш!
Иди на хуй, еболдыш!
Иди на хуй, еболдыш!
Иди на хуй, еболдыш!
Ruby [0] выдает
http://ideone.com/KTzQpn
x это тупл из листов, т.е. структура в которой лежат константные ссылки на не константные обьекты. При выполнении операции += для элемента тупла сначала вызывается оператор +
для листа и соответственно в лист добавляется 42 затем вызывается оператор = а этот оператор уже пытается изменить адрес листа который константный => вуаля мы ловим ошибку. Как то так.
Нет, не так. += — это самостоятельный оператор, он не раскладывается на + и =. Только мб если __iadd__ вдруг не определен в каком-нибудь пользовательском классе. Но у list __iadd__ определенно есть.
Там происходит что-то такое (то есть он раскладывается на '=' и __iadd__):
x[0] = x[0].__iadd__([42])
С поправкой на то, что x[0] вычисляется только один раз.
Обращаю внимание на DUP_TOP_TWO: один раз пара (x, 0) используется для BINARY_SUBSCR (__getitem__), второй раз - для STORE_SUBSCR (__setitem__).
Если iadd меняет сам обьект, то зачем присваивание? И как ты дизассемблил код?
http://docs.python.org/3.3/library/dis.html
сразу вспомнилось.
Дефолтовые значения аргументов функции вычисляются при компиляции, изменяемые объекты будут синглтонами. Конечно, большой вопрос - а нахуя так вообще сделали? Я бы назвал это багом.
И как я пропустил такой великий тред Победы?!