55

在代码中:

y = 7
x = y
x = 8

现在,y将是 7,x 将是 8。但实际上我想改变y. 我可以分配参考y并这样做吗?

例如,在 C++ 中,同样的事情可以实现为:

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

现在两者y&x将是 9

4

4 回答 4

72

你不能。正如其他答案指出的那样,您可以(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

这仍然不允许您为“常规”变量或对象字段起别名,但您可以有多个变量引用同一个Reference对象(对于 mutable-singleton-collection 替代方案也是如此)。您只需要小心始终使用.get()/ .set()(或[0])。

于 2012-06-27T09:07:00.150 回答
19

不,Python 没有这个功能。

如果你有一个列表(或任何其他可变对象),你可以通过改变 x 和 y 都绑定到的对象来做你想做的事情:

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

在线查看它:ideone

于 2012-06-27T08:45:27.857 回答
8

或者,您可以使用自制的容器。

class Value(object):
    def __init__(self, value): self.value = value

y = Value(7)
x = y
x.value = 8
print y.value

ideone

于 2012-06-27T09:05:56.437 回答
6

您应该为此使用可变对象。

在 python中x&y只是对对象的引用,所以y = 7意味着 y 指向 object 7x=y表示x也指向7,但由于7是不可变的,因此更改 x 的值只会更改对象7y仍然指向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]
于 2012-06-27T08:46:15.577 回答