Назначение ссылки на переменную Python

В коде

y = 7 x = yx = 8 

Теперь y будет 7, а x будет 8. Но на самом деле я хочу изменить y. Могу ли я присвоить ссылку y и сделать это?

Например, в C ++ то же самое можно достичь,

 int y = 8; int &x = y; x = 9; 

Теперь и y & x будет 9

Нет, ты не можешь. Как следует из другого ответа, вы можете (ab?) Использовать сглаживание изменчивых объектов для достижения аналогичного эффекта. Однако это не то же самое, что ссылки на C ++, и я хочу объяснить, что на самом деле происходит, чтобы избежать каких-либо заблуждений.

Вы видите, что в C ++ (и других языках) переменная (и поля объекта, и записи в коллекциях и т. Д.) Является местом хранения, и вы записываете значение (например, целое число, объект или указатель) на это место. В этой модели ссылки являются псевдонимом для места хранения (любого типа) – при назначении переменной без ссылки вы копируете значение (даже если это всего лишь указатель, это все еще значение) для места хранения; когда вы назначаете ссылку, вы копируете в место хранения где-то в другом месте. Обратите внимание, что вы не можете сами изменить ссылку – как только она привязана (и она должна быть как только вы ее создадите), все присваивания к ней изменяют не ссылку, а то, о чем говорится.

В Python (и других языках) переменная (и поля объекта, и записи в коллекциях и т. Д.) – это просто имя. Значения находятся гдето в другом месте (например, посыпаны по всей куче), а переменная ссылается (не в смысле ссылок на C ++, скорее как указатель минус арифметика указателя) на значение. Несколько имен могут ссылаться на одно и то же значение (что обычно хорошо). Python (и другие языки) вызывает все, что необходимо, чтобы ссылаться на значение ссылки, несмотря на то, что оно довольно не связано с такими вещами, как ссылки на C ++ и pass-by-reference. Присвоение переменной (или полем объекта или …) просто означает, что она ссылается на другое значение. Вся модель расположения хранилищ не относится к Python, программист никогда не обрабатывает места хранения для значений. Все, что он хранит и перемешивает, это ссылки на Python, и это не значения в Python, поэтому они не могут быть объектом других ссылок Python.

Все это не зависит от изменчивости значения – например, для int и списков одинаково. Вы не можете взять переменную, которая ссылается и на другую, и перезаписать объект, на который указывает. Вы можете только сообщать объекту об изменении частей самого себя – скажем, изменить содержащуюся в нем ссылку.

Является ли это более ограничительной моделью? Возможно, но это достаточно эффективно в большинстве случаев. И когда это не так, вы можете обойти это, либо с помощью специального класса, как тот, который приведен ниже, или (эквивалентный, но менее очевидный) одноэлементный набор.

 class Reference: def __init__(self, val): self._value = val # just refers to val, no copy def get(self): return self._value def set(self, val): self._value = val 

Это все равно не позволит вам псевдоним «регулярной» переменной или поле объекта, но вы можете иметь несколько переменных, относящихся к одному и тому же объекту Reference (например, для альтернативы mutable-singleton-collection). Вам просто нужно быть осторожным, чтобы всегда использовать .get() / .set() (или [0] ).

Нет, у Python эта функция отсутствует.

Если у вас есть список (или любой другой изменяемый объект), вы можете делать то, что хотите, путем изменения объекта, к которому привязаны как x, так и y:

 >>> x = [7] >>> y = x >>> y[0] = 8 >>> print x [8] 

Смотрите, как работает онлайн: ideone

Для этого вы должны использовать изменяемый объект.

В python x & y – это просто ссылки на объекты, так что y = 7 означает, что y указывает на объект 7 . x=y означает, что x тоже указывает на 7 , но поскольку 7 является неизменным, поэтому изменение значения x просто меняет объект 7 а y все еще остается указывать на 7 .

 >>> y = [7] >>> x = y >>> x[0] = 8 # here you're changing [7] not x or y, x & y are just references to [7] >>> y [8] 

Кроме того, вы можете использовать самодельный контейнер.

 class Value(object): def __init__(self, value): self.value = value y = Value(7) x = y x.value = 8 print y.value 

ideone