Python использует передачу по значению, но так как все эти значения являются ссылками на объектах, чистый эффект есть нечто родственное пройти по ссылке. Однако программисты Python больше думают о том, является ли тип объекта изменчивым или неизменным. Измененные объекты могут быть изменены на месте (например, словари, списки, определяемые пользователем объекты), тогда как неизменяемые объекты не могут (например, целые числа, строки, кортежи).
В следующем примере показана функция, передающая два аргумента, неизменяемая строка и изменяемый список.
>>> def do_something(a, b):
... a = "Red"
... b.append("Blue")
...
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']
Линия a = "Red"
просто создает локальное имя a
, для строкового значения "Red"
и не оказывает никакого влияния на переданное в аргументе (который теперь скрыт, как и a
должны ссылаться на локальное имя с тех пор). Назначение - это не операция на месте, независимо от того, является ли аргумент изменчивым или неизменяемым.
Параметр b
является ссылкой на изменяемый объект списка, а метод .append()
выполняет расширение на месте списка, привязывая к новому строковому значению "Blue"
.
(Поскольку строковые объекты являются неизменными, они не имеют каких-либо методов, которые поддерживают в месте изменения.)
После того, как функция возвращает, повторное назначение a
не имели никакого эффекта, в то время как расширение b
ясно показывает семантику стиля вызова по ссылке.
Как упоминался ранее, даже если аргумент a
является изменяемым типом, повторное назначение в функции не операция на месте, и поэтому не будет никаких изменений в значение пройденного аргумента:
>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']
Если вы не хотите, чтобы ваш список изменялся вызываемой функцией, вместо этого вы использовали бы неизменяемый тип кортежа (обозначенный скобками в литеральной форме, а не квадратными скобками), что не поддерживает на месте .append()
метод:
>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'
Здесь есть [уже ответ] (http://stackoverflow.com/questions/879/php-variables-passed-by-value-or-by-reference), который объясняет ситуацию в PHP5. – Mat 2008-08-05 09:02:31
Wow - этот вопрос имеет ссылку на бета-сервер. Я думаю, вы бета-исправление ссылки. – 2010-06-10 04:06:19