Аргументи в функціях. Передача аргументів у функцію. Зміна аргументів у тілі функції
Зміст
- 1. Як здійснюється передача аргументів у функцію? Робота механізму передачі аргументу в функцію
- 2. Приклади передачі незмінюваних об’єктів у функцію
- 3. Приклади передачі змінюваних об’єктів у функцію
- 4. Способи уникнення зміни об’єктів-аргументів у викликаючому коді
- 5. Особливості передачі аргументів у функцію. Підсумки
- Зв’язані теми
Пошук на інших ресурсах:
1. Як здійснюється передача аргументів у функцію? Робота механізму передачі аргументу в функцію
У функцію можуть передаватись аргументи. Аргументи – це змінювані або незмінювані об’єкти. У мові Python має значення, до якої категорії об’єктів (змінюваних чи незмінюваних) належить аргумент.
Наприклад, до змінюваних об’єктів відносяться списки та словники. До незмінюваних об’єктів відносяться числа, рядки, кортежі.
Якщо у функцію передається незмінюваний об’єкт, то цей об’єкт передається “за значенням”. Це означає, що зміна цього об’єкту всередині функції не змінить його у викликаючому коді.
Якщо у функцію передається змінюваний об’єкт, то це об’єкт передається за “покажчиком”. Зміна такого об’єкту всередині функції вплине на цей об’єкт у викликаючому коді.
⇑
2. Приклади передачі незмінюваних об’єктів у функцію
2.1. Передача числа у функцію
У прикладі, в демонстраційних цілях реалізована функція Mult2(), яка отримує параметром число. У тілі функції це число подвоюється. Отриманий результат виводиться.
# Передача числа у функцію # Число - це незмінюваний об'єкт, отже передається "за значенням" # Оголосити функцію, яка отримує деяке число і множить його на 2 def Mult2(number): # помножити число на 2 number = number*2 # вивести значення числа всередині функції print("Mult2.number = ", number) # Використати функцію num = 25 # деяке число Mult2(num) # викликати функцію # вивести число num після виклику функції print("num = ", num) # num = 25 - число не змінилось
Після запуску програма видасть наступний результат
Mult2.number = 50 num = 25
Як видно з результату, у функції значення числа num множиться на 2 і становить 50. Однак, цей результат не передається у викликаючий код, тут значення num залишається рівним 25 як до виклику функції. Це підтверджує передачу “за значенням” незмінюваного об’єкту, яким є число.
⇑
2.2. Передача рядка у функцію
Демонструється робота функції ReverseStr(), яка реверсує рядок, що був отриманий параметром.
# Передача рядка у функцію # Рядок - це незмінюваний об'єкт, тому передається "за значенням" # Оголосити функцію, яка отримує рядок, # реверсує його і виводить на екран def ReverseStr(text): # Реверсувати рядок txt = '' # цикл перебору рядка for c in text: txt = c + txt text = txt # вивести реверсований текст print('ReveseStr.text = ', text) # Виклик функції ReverseStr() Text = "Hello world!" ReverseStr(Text) print("Text = ", Text)
Результат виконання програми наступний
ReverseStr.text = !dlrow olleH Text = Hello world!
Як видно з результату, рядок у тілі функції змінюється (реверсується). Оскільки у функцію передається копія рядка, то в тілі функції змінюється тільки ця копія. Оригінал, що був переданий у функцію, при виклику функції не змінюється.
⇑
2.3. Передача кортежу в функцію
# Передача кортежу у функцію # Функція, яка отримує параметром кортеж def PassTuple(T): # Змінити кортеж T = ([1,2], 'a', 25.88) print('PassTuple.T = ', T) # Створити кортеж TT = ( [2, 3.5], True, 'abcd') # Викликати функцію і передати їй кортеж TT PassTuple(TT) # Вивести кортеж TT print('TT = ', TT)
Результат виконання програми
PassTuple.T = ([1, 2], 'a', 25.88) TT = ([2, 3.5], True, 'abcd')
Так само, як і в попередніх двох прикладах, передача кортежу у функцію відбувається за значенням.
⇑
3. Приклади передачі змінюваних об’єктів у функцію
3.1. Передача списку в функцію
Демонструється функція, яка отримує список в якості параметру. Потім у тілі функції цей список змінюється (змінюються перший та другий елементи списку).
# Передача списку у функцію. Список - змінюваний об'єкт # Функція, яка отримує параметром список def ChangeList(L): # Змінити список L[0] = 777 # Змінити перший елемент списку L[1] = (2, 3) # Змінити другий елемент списку # Вивести список в тілі функції print('ChangeList.L = ', L) # Створити список LL = [ [2, 3.5], True, 'abcd' ] # Вивести список LL для контролю print('LL = ', LL) # Викликати функцію і передати їй список LL ChangeList(LL) # Вивести список LL після виклику функції print('LL = ', LL)
Результат роботи програми
LL = [[2, 3.5], True, 'abcd'] ChangeList.L = [777, (2, 3), 'abcd'] LL = [777, (2, 3), 'abcd']
Як видно з результату, зміна списку у тілі функції приводить до зміни цього списку у викликаючому коді. Це означає, що список передається за принципом покажчика мови C.
⇑
3.2. Передача словника в функцію
Демонструється функція ChangeDict() яка отримує словник в якості параметру. У тілі функції змінюються окремі елементи словника, що лежать на позиціях з номерами 0 та 2.
# Передача словника у функцію. Словник - змінюваний об'єкт # Функція, яка отримує параметром словник def ChangeDict(D): # Змінити словник D['A'] = 100 # Змінити перший елемент списку D['C'] = 300 # Змінити третій елемент списку # Вивести список в тілі функції print('ChangeDict.D = ', D) # Створити словник DD = { 'A':5, 'B':10, 'C':20 } # Вивести словник DD для контролю print('DD = ', DD) # Викликати функцію і передати їй словник DD ChangeDict(DD) # Вивести список DD після виклику функції print('DD = ', DD)
Результат роботи програми
DD = {'A': 5, 'B': 10, 'C': 20} ChangeDict.D = {'A': 100, 'B': 10, 'C': 300} DD = {'A': 100, 'B': 10, 'C': 300}
⇑
4. Способи уникнення зміни об’єктів-аргументів у викликаючому коді
У випадках, коли потрібно заборонити зміну об’єкту списку всередині функції, можна використовувати способи які описані нижче.
Спосіб 1. При передачі списку в функцію можна конвертувати цей список в кортеж з допомогою операції tuple(). Після цього змінити список в тілі функції не вдасться.
Нижченаведений код демонструє використання операції tuple() для конвертування списку в кортеж.
# Передача списку в функцію з конвертуванням у кортеж def PassList(L): # Спроба змінити список L[0] = 100 # Помилка! # Вивести список в тілі функції print('PassList.L = ', L) # Створити список LL = [ 1, 3, 8, 10 ] # Викликати функцію і передати їй список LL, який конвертований у кортеж PassList(tuple(LL)) # Вивести список L після виклику функції print('LL = ', LL)
Список LL передається у функцію PassList() як кортеж
PassList(tuple(LL))
Після цього, змінити елемент списку LL в функції PassList() не вдасться. Якщо запустити програму, то буде згенеровано виключення з повідомленням
TypeError: 'tuple' object does not support item assignment
Спосіб 2. При передачі списку в функцію можна використати операцію зрізу [:], як показано у наступній програмі
# Передача списку в функцію з конвертуванням у зріз def PassList(L): # Спроба змінити список L[0] = 100 # Ця зміна не вплине на викликаючий код # Вивести список у тілі функції print('PassList.L = ', L) # Створити список LL = [ 1, 3, 8, 10 ] # Викликати функцію і передати їй список як зріз [:] PassList(LL[:]) # Вивести список L після виклику функції print('LL = ', LL)
У вищенаведеному коді при виклику функції з допомогою рядка
... PassList(LL[:]) ...
зріз LL[:] здійснює копію списку. Таким чином, зміни списку всередині функції не призведуть до зміни списку у викликаючому коді, оскільки ці зміни будуть виконуватись над копією.
Після запуску на виконання, програма видасть такий результат
PassList.L = [100, 3, 8, 10] LL = [1, 3, 8, 10]
⇑
5. Особливості передачі аргументів у функцію. Підсумки
Для аргументів, що передаються у функцію, можна виділити наступні особливості:
1. Якщо з зовнішнього коду викликається функція з передачею їй аргументу, то у тілі функції цей аргумент (об’єкт) автоматично присвоюється відповідній локальній змінній функції.
Наприклад. Демонструється автоматичне присвоєння локальній змінній функції значення аргументу.
# Аргументи. # Передача аргументу в функцію # Функція, яка отримує аргумент і виводить його на екран def Argument(v): print('Argument.v = ', v) return # Демонстрація неявного присвоєння value = 'Hello world!' # деякий об'єкт # передати об'єкт value у функцію Argument(), # відбувається неявне присвоєння Argument.v = value Argument(value) # Argument.v = Hello world!
2. Аргументи функції – це є посилання на об’єкти. При передачі аргументу в функцію передається посилання на об’єкт. Посилання, що передається, реалізоване як покажчики в мові C. Оскільки, при передачі у функцію аргументу, копіюється посилання на об’єкт, то сам об’єкт ніколи не копіюється. Іншими словами, не створюється автоматична копія об’єкту при передачі його в функцію, здійснюється тільки копія посилання.
3. Якщо в тілі функції присвоїти значення імені переданого параметру, то це не вплине на значення зовнішнього аргументу у викликаючому коді. Це пов’язане з тим, що імена аргументів у викликаючому коді стають новими іменами в області видимості функції.
Наприклад. У прикладі, в функції Func() змінюється значення параметру D на 25. У викликаючому коді був переданий аргумент з таким самим іменем D зі значенням 30. Однак, після виклику функції з викликаючого коду, значення зовнішнього аргументу D не змінилось, що й треба було довести.
# Аргументи. # Передача аргументу в функцію - копія об'єкту не робиться # Функція, що отримує аргумент-список def Func(D): D = 25 # тут D - нове ім'я print('Func.D = ', D) D = 30 Func(D) # виклик функції print('D = ', D) # D = 30 - значення об'єкту в функції не змінилось
4. Якщо в функцію передається аргумент (об’єкт), що є змінюваним (список, словник), то зміна цього аргументу всередині функції призведе до зміни аргументу у викликаючому коді. Це стосується тільки зміни складових елементів об’єкту (окремий елемент словника чи списку). Якщо спробувати змінити об’єкт за його загальним іменем (з допомогою операції присвоєння =), то змін у викликаючому коді не буде (передається посилання на об’єкт, а саме посилання змінити не можна).
Наприклад. У нижченаведеному прикладі оголошується дві функції, які роблять спробу змінити вхідний параметр-список за його іменем:
- функція ChangeList() – пробує змінити список за іменем посилання L. Ця зміна не впливає на зовнішній список LL, переданий з викликаючого коду. Це пов’язано з тим, що робиться копія посилання, зміни копії не змінюють оригінал;
- функція ChangeList2() – пробує змінити елемент списку за іменем посилання L та позицією елементу. Результат – зміна впливає на зовнішній список LL у викликаючому коді. Це пов’язано з тим, що копія і оригінал вказують на ті самі дані (ту саму ділянку пам’яті);
# Аргументи. # Передача змінюваного об'єкту в якості аргументу # Функція, що отримує параметр-список і змінює весь список def ChangeList(L): # Змінити список всередині функції за іменем L = [ 1, 2, 3] # не впливає на зовнішній код # Вивести змінений список print('ChangeList.L = ', L) # ChangeList.L = [1, 2, 3] # Функція, що отримує параметр-список і змінює елемент списку def ChangeList2(L): # Змінити складовий елемент списку L[1] = 'abcd' # впливає на зовнішній код print('ChangeList2.L = ', L) # ----- Викликаючий код модуля ------- LL = [ 'a', 'b', 'c' ] # деякий список # 1. Передача списку в функцію ChangeList() та його вивід ChangeList(LL) # передати список у функцію print('LL = ', LL) # LL = ['a', 'b', 'c'] - список не змінився # 2. Передати список LL у функцію ChangeList2() ChangeList2(LL) print('LL = ', LL) # LL = ['a', 'abcd', 'c' ] - список змінився
Після виконання програма видасть наступний результат
ChangeList.L = [1, 2, 3] LL = ['a', 'b', 'c'] ChangeList2.L = ['a', 'abcd', 'c'] LL = ['a', 'abcd', 'c']
⇑
Зв’язані теми
- Режими співставлення аргументів. Класифікація. Співставлення за позицією. Співставлення за іменами. Аргументи за замовчуванням
- Режими співставлення аргументів. Аргументи змінної довжини. Комбінування різних способів співставлення аргументів. Приклади
⇑