Глава 13 · Автоматизация с помощью функций
Изменяемые и неизменяемые аргументы
Один из самых важных уроков главы: присваивание параметру и мутация объекта, на который он указывает, — это два совершенно разных действия.
Неизменяемый аргумент: rebinding не выходит наружу
immutable_argument.py
def add_one(number):
number += 1
print(number)
x = 10
add_one(x)
print(x)
11
10
Не «функция получает копию x»
Точнее:
number сначала указывает туда же, куда и x (на 10). Но number += 1 — это number = number + 1: создаётся НОВЫЙ объект 11, и number начинает указывать на него. x по-прежнему указывает на старый объект 10 — они разошлись.Изменяемый аргумент: мутация видна снаружи
mutable_argument.py
def add_item(items):
items.append("Python")
skills = ["Git"]
add_item(skills)
print(skills)
['Git', 'Python']
Это не магия — это тот же aliasing из главы 11
items внутри функции указывает на ТОТ ЖЕ объект-список, что и skills снаружи. .append(...) мутирует этот общий объект — поэтому изменение видно через оба имени. Это ровно тот же принцип aliasing, что мы разбирали в §11.9, только теперь одно из «двух имён» — параметр функции.Rebinding vs mutation — сравниваем напрямую
rebinding_vs_mutation.py
def replace(items):
items = ["new"] # rebinding: items теперь указывает на ДРУГОЙ список
def modify(items):
items.append("new") # mutation: меняется ТОТ ЖЕ список
| replace(items) | modify(items) | |
|---|---|---|
| Что происходит | переприсваивание локального имени items | изменение объекта, на который items указывает |
| Видно снаружи после вызова? | нет — снаружи всё как было | да — тот же объект изменился |
Главное практическое правило
Присваивание параметру (
items = ...) отвязывает локальное имя от аргумента — снаружи ничего не меняется. Вызов мутирующего метода (.append(), .sort(), [i] = ...) меняет сам объект — и это видно снаружи, если объект изменяемый.Практика: rebinding vs mutation
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки