Найти тему

Летающий цирк

Вычитал неплохой тест на то, как отделить человека, освоившегося с Python, от человека, который «ну там, синтаксис знаю».

Код на картинке, поскольку нынешние сети, в отличие от старого доброго ЖЖ, не умеют в преформат.

Задача испытуемого – ответить, что выдаст код.

Человек, который просто знает синтаксис, возможно, представит себе примерно следующее.

Второй параметр функции имеет значение по умолчанию, а именно пустой список. Значит, видимо, когда он пропущен, в функцию вторым параметром передаётся пустой список. Значит, в первый раз должно вывести "[0, 1]", а во второй "[0, 1, 2]".

Не, деца, сбъркахте.

Фишка в том, что Python язык не просто интерпретируемый, это язык «предельно интерпретируемый». То есть там в принципе нет «чистаа определений», все операторы исполняются. Даже такие, как, например, import. Да-да. Автор модуля может в него встроить код на верхнем уровне, и этот код выполнится немедленно в момент выполнения оператора import.

Оператор "def" – это не как в компилируемых языках, просто определение функции. Это выполнение инструкции «определить функцию». Соответственно, всё то, что мы понаписали как тело функции, конечно, прямо тут выполнено не будет, оно будет выполняться при вызове. А вот то, что написано в собственно def, шапочка функции, будет выполнено немедленно.

То есть.

При выполнении данного def интерпретатор _создаст_ объект [] (пустой список), и запомнит, что если функция не получила второй параметр, в качестве второго параметра надо передавать вот этот вот объект.

Соответственно, при собственно вызовах нашей функции (из print) пустых списков создаваться не будет. Вторым методом будет передан ранее созданный объект, который перед первым вызовом был пустой, а в ходе работы первого вызова мы успели туда накидать полную панамку.

Поэтому правильный ответ: в первый раз выведет "[0, 1]", а во второй вовсе даже "[0, 1, 0, 1, 2]"

#лаборофилия