Python: В чем разница между вызовом по значению и вызовом по объекту?

#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. Очень интересно. Спасибо.