https://habr.com/ru/company/otus/blog/459518/- Блог компании OTUS. Онлайн-образование
- Python
- Программирование
- Карьера в IT-индустрии
Салют, хабровчане! В преддверии запуска нового потока по курсу
«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]
Заключение
Вот я и разобрал одну из самых популярных тестовых задач на собеседовании. Этот пост призван показать, что вы не всегда можете полагаться на свою интуицию, впрочем, как и я на свою :-).
Надеемся данный перевод станет полезным для вас. Традиционно ждем комментарии и до встречи на
курсе.