【问题标题】:Shared References and Equality共享参考和平等
【发布时间】:2015-03-02 00:12:52
【问题描述】:

使用 Python 3.4 并研究 O'Reily 所著书籍中的示例。 示例显示:

A = ['spam']
B = A
B[0] = 'shrubbery'

运行print A后的结果:

'shrubbery'

现在我的想法是A 已定义但从未改变。

这个例子产生了不同的结果

A = 'string'
B = A
B = 'dog'

这是运行print A后的结果:

'string'

谁能解释一下?

【问题讨论】:

标签: python list equals


【解决方案1】:

在第一个示例中,您正在修改B 引用的列表。

在做:

B[0] = 'shrubbery'

告诉 Python 将B 引用的列表中的第一项设置为'shrubbery' 的值。此外,该列表恰好与A 引用的列表相同。这是因为:

B = A

导致BA 各自引用同一个列表:

>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>

因此,对B 引用的列表的任何更改也会影响A 引用的列表(反之亦然),因为它们是同一个对象。


然而,第二个示例没有修改任何内容。相反,它只是重新分配名称 B 到一个新值。

一旦这行被执行:

B = 'dog'

B 不再引用字符串 'string',而是引用新字符串 'dog'。同时A的值保持不变。

【讨论】:

    【解决方案2】:

    与大多数现代动态语言一样,python 中的变量实际上是类似于 C 指针的引用。这意味着当您执行 A = B 之类的操作(其中 A 和 B 都是变量)时,您只需让 A 指向与 B 相同的内存位置。

    在第一个示例中,您正在就地改变(修改)现有对象——这就是variable_name[index/key] = value 语法所做的。 A 和 B 都继续指向同一个东西,但这个东西的第一个条目现在是“灌木”,而不是“垃圾邮件”。

    在第二个示例中,当您说B = 'dog' 时,您将 B 指向另一个(此时为新)对象。

    【讨论】:

      【解决方案3】:

      希望你能这样理解:-)

      正如您在第一种方法中看到的,它们都引用相同的list,第二个不同。所以在第二种方法中更改不会影响另一个。

      【讨论】:

      • @NoMorePuppies 我认为这是一个很好的解释,但我也认为纯图形答案在 SO 中是不可接受的 - 它们不可搜索且不可重复,并且不尊重可访问性标准
      【解决方案4】:

      可变对象是列表,而字符串是不可变的,这就是为什么您可以更改内存地址和列表本身,但不能更改字符串。

      【讨论】:

        【解决方案5】:

        以下是两者的区别:

        下面是一步一步的分析:

        A = ['spam']
        "A points to a list whose first element, or A[0], is 'spam'."
        B = A
        "B points to what A points to, which is the same list."
        B[0] = 'shrubbery'
        "When we set B[0] to 'shrubbery', the result can be observed in the diagram.
        A[0] is set to 'shrubbery' as well."
        print (A):
        
        
        
        A = 'string'
        "A points to 'string'."
        B = A
        "B points to what A points to, which is 'string'."
        B = 'dog'
        "Oh look! B points to another string, 'dog', now.
        So does what A points to change? No."
        The result can be observed in the diagram.
        print (A):
        

        【讨论】:

        • Python 中没有“原始类型”。所有值都是对象。这纯粹是名称绑定的问题。
        • @kindall 请看看我的回答现在是否正确。感谢您指出了这一点!我一直在想 Java...
        • 在第二种情况下,A 和 B 仍然是指向字符串对象的指针。他们自己没有价值。 Python 中的所有变量都存储对对象的引用。
        • 措辞不当...让我更正一下。 @kindall
        • @kindall 现在怎么样?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 1970-01-01
        • 2020-08-24
        • 1970-01-01
        • 2020-09-11
        相关资源
        最近更新 更多