Все мы знаем догму о том, что глобальные переменные - это плохо. Когда я начал изучать Python, я прочитал, что параметры, передаваемые функциям, рассматриваются как локальные переменные внутри функции. Кажется, это как минимум половина правды:
def f(i):
print("Calling f(i)...")
print("id(i): {}\n".format(id(i)))
print("Inside f(): i += 1")
i += 1
print("id(i): {}".format(id(i)))
return
i = 1
print("\nBefore function call...")
print("id(i): {}\n".format(id(i)))
f(i)
Это оценивается как:
Before function call...
id(i): 507107200
Calling f(i)...
id(i): 507107200
Inside f(): i += 1
id(i): 507107232
Насколько я сейчас читаю, механизм вызова функций в Python - это «Вызов по ссылке на объект». Это означает, что аргумент изначально передается посредством ссылки на объект, но если он изменяется внутри функции, создается новая объектная переменная. Мне кажется разумным избегать дизайна, в котором функции непреднамеренно изменяют глобальные переменные.
Но что произойдет, если мы передадим список в качестве аргумента?
def g(l):
print("Calling f(l)...")
print("id(l): {}\n".format(id(l)))
print("Inside f(): l[0] += 1")
l[0] += 1
print("id(l): {}".format(id(l)))
return
l = [1, 2, 3]
print("\nBefore function call...")
print("id(l): {}\n".format(id(l)))
g(l)
Это приводит к:
Before function call...
id(l): 120724616
Calling f(l)...
id(l): 120724616
Inside f(): l[0] += 1
id(l): 120724616
Как видим, ссылка на объект осталась прежней! Итак, мы работаем с глобальной переменной, не так ли?
Я знаю, что мы можем легко преодолеть это, передав копию списка в функцию с помощью:
g(l[:])
Но мой вопрос: в чем причина того, что в Python реализованы два разных поведения параметров функции? Если мы намереваемся манипулировать глобальной переменной, мы могли бы также использовать «глобальное» -ключевое слово для списка, как мы это сделали бы для целых чисел, не так ли? Как такое поведение согласуется с дзеном Python «явное лучше, чем неявное»?
list
изменяемые иint
объекты неизменяемые, их поведение отображается отличаться. - person jonrsharpe   schedule 06.11.2014