在代码中
y = 7
x = y
x = 8
Run Code Online (Sandbox Code Playgroud)
现在,y将是7,x将是8.但实际上我想改变y.我可以指定y的参考并执行此操作吗?
例如,在C++中可以实现同样的目的,
int y = 8;
int &x = y;
x = 9;
Run Code Online (Sandbox Code Playgroud)
现在y&x都是9
小智 56
你不能.正如其他答案所指出的,你可以(ab?)使用可变对象的别名来实现类似的效果.但是,这与C++引用不同,我想解释实际发生的事情以避免任何误解.
您可以看到,在C++(和其他语言)中,变量(和对象字段以及集合中的条目等)是存储位置,您可以编写一个值(例如,整数,对象或指针)那个位置.在此模型中,引用是存储位置(任何类型)的别名 - 当您分配给非引用变量时,您将一个值(即使它只是一个指针,它仍然是一个值)复制到存储位置; 分配给引用时,将其复制到其他位置的存储位置.请注意,您无法更改引用本身 - 一旦它被绑定(并且必须在创建它之后),所有对它的赋值都不会改变引用,而是引用任何引用.
在Python(和其他语言)中,变量(和对象字段以及集合中的条目等)只是一个名称.值在其他地方(例如,遍布堆遍),并且变量引用(不是在C++引用的意义上,更像是指针减去指针算术)到值.多个名称可以引用相同的值(这通常是一件好事).Python(和其他语言)调用引用值作为引用所需的任何内容,尽管与C++引用和传递引用等内容非常无关.分配给变量(或对象字段,或......)只会使其引用另一个值.整个存储位置模型不适用于Python,程序员从不处理值的存储位置.所有他存储和随机播放都是Python引用,而这些不是Python中的值,因此它们不能成为其他Python引用的目标.
所有这些都与值的可变性无关 - 例如,对于整数和列表,它是相同的.您不能获取引用它们的变量,并覆盖它指向的对象.你只能告诉对象修改它自己的部分 - 比如,改变它包含的一些引用.
这是一个限制性更强的模型吗?或许,但它在大多数时候都足够强大.当它不是时,你可以解决它,或者使用下面给出的自定义类,或者(等效但不太明显)单元素集合.
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
Run Code Online (Sandbox Code Playgroud)
这仍然不允许您为"常规"变量或对象字段添加别名,但是您可以使用多个变量来引用同一个Reference
对象(对于mutable-singleton-collection备选方案也是如此).你必须要小心,始终使用.get()
/ .set()
(或[0]
).
Mar*_*ers 17
不,Python没有此功能.
如果你有一个列表(或任何其他可变对象),你可以通过改变x和y绑定的对象来做你想要的事情:
>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]
Run Code Online (Sandbox Code Playgroud)
看到它在线工作:ideone
或者,您可以使用自制的容器。
class Value(object):
def __init__(self, value): self.value = value
y = Value(7)
x = y
x.value = 8
print y.value
Run Code Online (Sandbox Code Playgroud)
你应该使用一个可变对象.
在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]
Run Code Online (Sandbox Code Playgroud)