Тест самоперевірки

Аргументи й область видимості

Обери відповідь — і одразу побачиш пояснення. Помилитись тут корисніше, ніж на іспиті.

← до лекції
Відповіді0 / 8   правильних: 0
Питання 1 / 8

Функція def додати(товар, кошик=[]) робить кошик.append(товар) і повертає кошик. Її викликали тричі підряд: додати('яблуко'), додати('груша'), додати('слива'). Що поверне ТРЕТІЙ виклик?

Чому так. Порожній список створюється один раз — коли Python виконує рядок def, — і лежить у додати.__defaults__. Кожен виклик без аргументу отримує не новий список, а той самий, уже з усім, що накидали раніше. Варіант [ʼсливаʼ] — це те, чого від функції чекають, і саме тому пастка така підступна: помилки немає, є тихо неправильна відповідь.
Питання 2 / 8

Пастку виправляють через кошик=None. Чому перевірка «if not кошик: кошик = []» гірша за «if кошик is None: кошик = []»?

Чому так. Порожній список «неправдивий», тому not дасть True і для None, і для []. Функція заведе свій новий список, а той, який їй передали, лишиться порожнім — і той, хто викликав, нічого не отримає. Питання ж не «чи він порожній», а «чи його передали», і відповідає на нього саме is None.
Питання 3 / 8

Є def оформити(товар, кількість=1, знижка=0.0). Що станеться при виклику оформити('мед', 3, кількість=2)?

Чому так. Трійка лягає на «кількість» за позицією, а «кількість=2» — за іменем. Python не обирає між ними й не бере останнє: він одразу дає TypeError: got multiple values for argument, і тіло функції не виконується жодного рядка. SyntaxError тут не буде — рядок синтаксично коректний, помилка виникає під час виконання.
Питання 4 / 8

Зовні є кошик = ['хліб']. Функція def замінити(список) робить у тілі список = ['мед'] і нічого не повертає. Що буде в кошику після виклику замінити(кошик)?

Чому так. Присвоєння всередині функції перечіпляє тільки локальне імʼя «список» на новий обʼєкт; зовнішнє імʼя «кошик» лишається на старому списку, і новий помирає одразу після виходу з функції. Якби в тілі стояло список.append(ʼмедʼ), змінився б сам обʼєкт — і кошик став би [ʼхлібʼ, ʼмедʼ].
Питання 5 / 8

Імʼя «підсумок» не оголошене ні локально, ні в обгортці, ні на рівні модуля. Що станеться при print(підсумок)?

Чому так. Пошук LEGB пройде всі чотири рівні й не знайде нічого: серед вбудованих імені «підсумок» немає. Це NameError — та сама помилка, що виникає від звичайної одруківки в імені. Порівняй із sum: воно вбудоване, тому для нього пошук завжди чимось закінчується, хоч би що ти оголосив.
Питання 6 / 8

На рівні модуля є лічильник = 0. Усередині функції написано лічильник = лічильник + 1, заяви global немає. Що станеться при виклику?

Чому так. Присвоєння будь-де в тілі робить імʼя локальним для всієї функції — від першого рядка, а не з місця присвоєння. Тому праворуч від «=» Python шукає лічильник лише в локальній памʼяті, знаходить його оголошеним, але ще ні на чому не звʼязаним. Останній варіант був би правильний, якби праворуч не стояло те саме імʼя.
Питання 7 / 8

На рівні модуля є підсумки = []. Функція робить підсумки.append(5) — без жодної заяви global — і це працює. Чому?

Чому так. Локальним імʼя робить саме присвоєння, а виклик метода присвоєнням не є: «підсумки» так і залишилось глобальним іменем, а append відредагував обʼєкт у місці. Тип тут ні до чого — рядок підсумки = [5] у тому самому місці створив би локальне імʼя, і глобальний список лишився б порожнім.
Питання 8 / 8

позиція = ['мед', 3, 0.1]. Чим відрізняються виклики оформити(позиція) і оформити(*позиція)?

Чому так. Зірочка у виклику розкладає послідовність на окремі позиційні аргументи. Без неї список іде цілим і потрапляє в перший параметр «товар» — далі пошук у словнику цін впаде з TypeError: unhashable type. Зірочка змінює кількість аргументів, а не їхні значення.