Python: когда переменная передается по ссылке и когда по значению? [дубликат]

Возможные Дубликаты:
Python: как передать переменную по ссылке?

мой код :

locs = [ [1], [2] ]
for loc in locs:
    loc = []

print locs
# prints => [ [1], [2] ]

почему loc ссылки элементов locs ?

Python: все передается как ссылка, Если явно не скопировано [ это не так ? ]

Пожалуйста, объясните.. как python решает использование и копирование ?

обновление :

как это сделать ?

def compute(ob):
   if isinstance(ob,list): return process_list(ob)
   if isinstance(ob,dict): return process_dict(ob)

for loc in locs:
   loc = compute(loc)  # What to change here to make loc a reference of actual locs iteration ?
  • Loc должны содержать окончательный обработанный ответ !
  • я не хочу использовать enumerate, возможно ли это без него ?

6 ответов


все в Python передается и назначается по значению, так же, как все передается и назначается по значению в Java. Каждое значение в Python является ссылкой (указателем) на объект. Объекты не могут быть значениями. Присваивание всегда копирует значение (которое является указателем); два таких указателя могут, таким образом, указывать на один и тот же объект. Объекты никогда не копируются, если вы не делаете что-то явное для их копирования.

для вашего случая каждая итерация цикла назначает элемент список в переменную loc. Затем вы назначаете что-то еще переменной loc. Все эти значения являются указателями; вы назначаете указатели; но вы никоим образом не влияете на какие-либо объекты.


Effbot (он же Фредрик Лундх) описал стиль передачи переменных Python как call-by-object:http://effbot.org/zone/call-by-object.htm

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

  • когда вы делаете назначение, такие как x = 1000, создается запись словаря, которая сопоставляет строку "x"в текущем пространстве имен с указателем на целочисленный объект, содержащий тысячу.
  • при обновлении "x" с x = 2000, создается новый объект integer и словарь обновляется, чтобы указать на новый объект. Старый объект "тысяча" не изменился (и может быть или не быть живым в зависимости от того, относится ли что-либо еще к объекту).
  • когда вы делаете новое задание, такие как y = x, создается новая запись словаря "y", которая указывает на тот же объект, что и запись для"x".
  • объекты, такие как строки и целые числа неизменяемые. Это просто означает, что нет методов, которые могут изменить объект после его создания. Например, как только будет создан объект integer one-thousand, он никогда не изменится. Математика выполняется путем создания новых объектов integer.
  • объекты, такие как списки mutable. Это означает, что содержимое объекта может быть изменено чем угодно, указывающим на объект. Например, x = []; y = x; x.append(10); print y печати [10]. Был создан пустой список. Как "X" и "y" указывают на один и тот же список. The добавить метод мутирует (обновляет) объект списка (например, добавляет запись в базу данных), и результат виден как "x", так и "y" (так же, как обновление базы данных будет видно для каждого подключения к этой базе данных).

надеюсь, что это проясняет вопрос для вас.


это не помогает в Python думать в терминах ссылок или значений. Ни правильно.

в Python переменные-это просто имена. В ваш цикл for, loc - это просто имя, которое указывает на текущий элемент в списке. Делать loc = [] просто rebinds имя loc в другой список, оставив только оригинальную версию.

но так как в вашем примере, каждый элемент списка, вы могли бы на самом деле мутировать этот элемент, и что будет отражено в исходном списке:

for loc in locs:
    loc[0] = loc[0] * 2

когда вы говорите

loc = []

вы подменой loc переменная для вновь созданного пустого списка

возможно, вы хотите

loc[:] = []

который присваивает срез (который, оказывается, весь список) loc пустому списку


все передается объектом. Восстановление и мутация-это разные операции.

locs = [ [1], [2] ]
for loc in locs:
    del loc[:]

print locs

почему loc не является ссылкой на элементы Loc ?

это. Или, по крайней мере, в том же смысле, что и любая другая переменная в Python. Переменные в Python являются имена, а не хранения. loc - это имя, которое используется для обозначения элементов [[1,2], [3,4]], а locs - это имя, которое относится ко всей структуре.

loc = []

этой не значит " посмотрите на эту штуку, что loc имена, и заставьте его превратиться в []". Это не может означает это, потому что объекты Python являются не способен такую вещь.

вместо этого это означает "причина loc чтобы перестать быть имя, что это настоящее имя, и начать вместо этого имя []". (Конечно, это означает конкретное [] это при условии, так как в общем может быть несколько объектов в памяти, которые являются одинаковыми.)

естественно, содержание из locs остаются неизменными в результате.