#python #arrays #scope
Вопрос:
Многие люди говорят, что в Python аргументы функций передаются с использованием модели вызова по значению. Насколько я понимаю, на самом деле это не язык вызова по значению, а модель вызова по объекту или совместного использования вызовов.
В чем различия между моделью вызова по значению и моделью вызова по объекту? Какой пример в Python показывает, чем отличаются эти модели?
Комментарии:
1. Это «передача по ссылке» или «передача по значению».
2. Также «вызов по ссылке» и «вызов по значению».
3. Я предпочитаю думать об этом как о «вызове по значению ссылки».
4. @gnibbler — вы имеете в виду, имея в виду конкретно Python?
5. @cytinus, Да, хотя это может относиться и к другим языкам.
Ответ №1:
Переменные в Python-это не значения, это ссылки на объекты. При вызове функции Python аргументы являются копиями ссылок на исходный объект. Я не знаю, как это связано с терминологией, которую вы задали в вопросе.
Например, рассмотрим следующий код Python:
def foo(bar, baz): bar = 3 baz[0] = 4 a = 1 b = [2] foo(a, b) print a, b
a
присваивается объекту 1
и b
назначается объекту списка , содержащему ссылку на объект 2
. Внутри функции foo
bar
также назначается одному и тому же объекту 1
и baz
назначается одному и тому же объекту списка. Так 1
как неизменен, вы не можете изменить объект, но вы можете переназначить bar
, чтобы ссылаться на другой объект, например 3
. Список можно изменить, поэтому, установив baz[0]
4
значение «вы», вы также изменяете объект списка, на который b
ссылается. Результатом вышесказанного будет 1 [4]
.
Комментарии:
1. Блестящее объяснение. Особенно концепция ссылок на объекты.
Ответ №2:
Говорить, что это не проходное значение, неверно. Семантически это передача по значению, и можно продемонстрировать семантическую эквивалентность между ним и другими языками передачи по значению. Однако он относится к определенной подкатегории языков передачи значений, где все значения являются ссылками (указателями) на объекты (у вас не может быть объекта в качестве значения напрямую), и многие люди путают указатель на объект с самим объектом. Такие языки включают Java (в отношении объектов), Python, Ruby, JavaScript, Scheme, Smalltalk, и это лишь некоторые из них.
Путаницу усугубляет то, что сообщества разных языков используют разную терминологию. Например, сообщество Java последовательно описывает Java как передаваемое значение, хотя объекты в Java имеют точно такую же семантику, что и объекты в Python и Ruby. Однако в сообществах этих последних языков вы гораздо реже слышите «передаваемое значение».
Передача по значению и передача по ссылке-это, по сути, семантическое различие, а не то, для чего оно используется. Но многие (начинающие) программисты не так сильно заботятся о семантике, а больше заботятся о том, для чего ее можно использовать. Например, некоторые люди думают, что всякий раз, когда у вас есть «У меня есть некоторые данные, которые я передаю функции, и она может изменить их, не возвращая, и я могу видеть изменения», это означает передачу по ссылке, фактически не задумываясь (или не заботясь) о том, была ли измененная вещь тем, что вы передали, или чем-то, на что косвенно указывала вещь, которую вы передали.
«Передача по объекту» или «передача по совместному использованию» или что-то еще-это термин, который придуман для описания комбинации семантики передачи по значению наряду с тем, чтобы все значения были ссылками (указателями). Таким образом, они могут легче выразить фактические эффекты такой комбинации и отличить ее, например, от эффектов передачи значения в C. Но семантически это все равно проходное значение. Утверждение о том, что переменные являются «именами» или «дескрипторами», которые «привязаны» к объектам и что, когда вы назначаете или передаете их, вы делитесь объектом, являетсяв точности эквивалентно утверждению, что переменные (и фактически все значения в языке) являются указателями на объекты, и когда вы назначаете или передаете их, эти указатели копируются по значению.
Комментарии:
1. Очень интересно. Спасибо.