Я думал, что Python передал все по ссылке? - PullRequest
6 голосов
/ 18 ноября 2011

Возьмите следующий код

#module functions.py
def foo(input, new_val):
    input = new_val

#module main.py
input = 5
functions.foo(input, 10)

print input

Я думал, что теперь ввод будет 10. Почему это не так?

Ответы [ 4 ]

13 голосов
/ 18 ноября 2011

Все передается по значению, но это значение является ссылкой на исходный объект. Если вы измените объект, изменения будут видны для вызывающей стороны, но вы не сможете переназначить имена. Более того, многие объекты являются неизменяемыми (целые числа, числа с плавающей запятой, строки, кортежи).

8 голосов
/ 18 ноября 2011

Внутри foo вы привязываете локальное имя input к другому объекту (10).В контексте вызова имя input по-прежнему относится к объекту 5.

5 голосов
/ 18 ноября 2011

Назначение в Python не изменяет объект на месте. Он связывает имя так, что после input = new_val локальная переменная input получает новое значение.

Если вы хотите изменить «снаружи» input, вам придется обернуть его внутри изменяемого объекта, такого как список из одного элемента:

def foo(input, new_val):
    input[0] = new_val

foo([input])

Python не выполняет передачу по ссылке в точности так, как работает передача ссылок в C ++. В этом случае, по крайней мере, все, как будто каждый аргумент является указателем в C / C ++:

// effectively a no-op!
void foo(object *input, object *new_val)
{
    input = new_val;
}
3 голосов
/ 18 ноября 2011

Python не является ни вызовом по значению, ни вызовом по ссылке, это Вызов по объекту .

"Аргументы передаются по вызову путем разделения, аналогично для вызова по значению, за исключением , что аргументы являются объектами и могут быть изменены только в том случае, если они изменяемы. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...