Салют! В преддверии запуска нового потока по курсу «Web-разработчик на Python» хотим поделиться новым полезным переводом. Поехали!
Снова сходив на несколько собеседований и пройдя тестовые задания, я заметил, что интервьюерам нравятся задания наподобие следующего.
def f(x, l=[]):
for i in range(x):
l.append(i * i)
return l
>>> f(2)
>>> f(3, [0, 1, 2])
>>> f(3)
Вопрос: Что выведет этот код?
Вывод первых двух строк достаточно очевиден, однако результат выполнения третьей строки f(3)
не показался мне таким однозначным. Давайте посмотрим, что происходит после инициализации функции f
. Чтобы запустить этот код, я воспользуюсь IPython.
>>> f
<function __main__.f(x, l=[])>
>>> f.__defaults__
([],)
Пустой список, который мы видим из результата выполнения f.__defaults__
— это переменная l
в коде функции.
>>> f(2)
[0, 1]
Ничего особенного.
>>> f
<function __main__.f(x, l=[0, 1])>
>>> f.__defaults__
([0, 1],)
Однако! Теперь мы видим, что переменная l
имеет значение [0, 1]
в силу изменчивости объекта списка в Python и передачи аргументов функции в качестве ссылки.
>>> f(3, [0, 1, 2])
[0, 1, 2, 0, 1, 4]
>>> f
<function __main__.f(x, l=[0, 1])>
Тоже ничего особенного. Просто передача объекта list
в качестве переменной l
.
>>> f(3)
[0, 1, 0, 1, 4]
>>> f
<function __main__.f(x, l=[0, 1, 0, 1, 4])>
А вот теперь самое интересное. Когда вы запускаете f(3)
, Python не использует пустой список, который определен в коде функции, он использует переменную l
со значениями из f.__defaults__ ([0, 1])
.
P.S.
Если вам нужна функция, которая использует пустой список после каждого вызова, вам следует использовать что-то вроде этого (установить значение ‘l’
в ‘None’
).
def f(x, l=None):
if l is None:
l = []
for i in range(x):
l.append(i * i)
return l
>>> f(2)
[0, 1]
>>> f(3, [0, 1, 2])
[0, 1, 2, 0, 1, 4]
>>> f(3)
[0, 1, 4]
Заключение
Вот я и разобрал одну из самых популярных тестовых задач на собеседовании. Этот пост призван показать, что вы не всегда можете полагаться на свою интуицию, впрочем, как и я на свою :-).
Надеемся данный перевод станет полезным для вас. Традиционно ждем комментарии и до встречи на курсе.
Автор: MaxRokatansky