【问题标题】:How to create a reference to a variable in python?如何在python中创建对变量的引用?
【发布时间】:2012-06-28 15:54:12
【问题描述】:

在代码中:

y = 7
x = y
x = 8

现在,y 将是 7,x 将是 8。但实际上我想更改 y。我可以分配y 的引用并这样做吗?

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

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

现在yx 都将是 9

【问题讨论】:

    标签: python reference


    【解决方案1】:

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

    在 python 中,x & y 只是对对象的引用 所以y = 7 表示y 指向对象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]
    

    【讨论】:

    • 您想指出即使在更改 x 之后 y 也保持不变,但这不是您在此处写的。请澄清。
    【解决方案2】:

    不,Python 没有此功能。

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

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

    在线查看:ideone

    【讨论】:

    • 虽然这确实很有帮助,但在这个单一简单数值的“突变”中或多或少有很大的缺点。用单个元素转换列表中的整数需要的内存空间是您通常需要的内存空间的 3 倍多一点。示例(我将使用 sys.getsizeof(...) 来说明大小差异):x = 1 -> sys.getsizeof(x) -> 给我们 14 -> x = [1] -> sys.getsizeof (x) -> 给我们 36
    【解决方案3】:

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

    【讨论】:

    • 很好的解释,+1 澄清它与可变性无关。
    • 谁能解释这个答案中 (ab?) 的含义?
    • @Daniel Roseman 你能解释一下这个答案中 (ab?) 的含义吗?
    • 这是一个很好的答案,我认为它是成为社区答案的好人选。为每个范例添加语言示例也可能非常有用。
    • @FadyHany 我认为您可以将“您可以(ab?)使用别名”部分阅读为“您可以使用别名”或“您可以滥用别名”,这表明此解决方法可能被一些开发者认为是 hacky。
    【解决方案4】:

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

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

    ideone

    【讨论】:

      猜你喜欢
      • 2016-11-19
      • 2017-10-31
      • 1970-01-01
      • 2023-03-27
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多