【问题标题】:Python Changes Both Variables When Set Equal?当设置相等时,Python 会更改两个变量?
【发布时间】:2016-06-03 14:24:52
【问题描述】:

在使用 python 时,我注意到一个非常奇怪的行为,它将 2 个设置相等的变量绑定到相同的更改,我想知道是否有人对此行为有解释,以及是否有比我更好的解决方案它。

例如,我有一个名为 schema1 的数组。后来我需要用一组新的变量扩展 schema1,但我不能弄乱原始数组,所以我通过将它设置为 schema1 来创建 schema2,如下所示:

    from someFileICreated import SomeClass

      schema1 = SomeClass.SomeSchema 

假设schema1有数组[a, b, c],那么I:

      schema2 = schema1
      schema2.append(d, e, f)

现在,schema2 应该有 [a, b, c, d, e, f] 但是,由于某种原因,schema1 也有 [a, b, c, d, e, f]

我不明白这种行为,所以如果你有一个很好的解释。就解决方案而言,这将起作用,但我想知道是否有另一种更好的方法可以避免循环。

我没有设置 schema2 = schema1,而是这样做:

    schema2 = []
    for x in schema1:
        schema2.append(x)

【问题讨论】:

  • Python 变量是对对象的引用;您有一个具有多个引用的对象。

标签: python variables


【解决方案1】:

重要的是要记住,在 Python 中,变量不是存放东西的小盒子,它们只是附加到东西上的方便名称。

所以当你这样做时

schema1 = SomeClass.SomeSchema
schema2 = schema1

您只是将两个名称附加到同一条数据,这就是两个变量的值发生变化的原因。

您需要复制实际值。对于列表,一种方法是:

schema2 = schema1[:]

有关复制列表的更多信息,请参阅this question

【讨论】:

  • 谢谢您,先生,这对我来说是一个非常棒的时刻。
【解决方案2】:

在这一行:

schema2 = schema1

您没有创建 new 数组,而是将引用 schema2 设置为指向 schema1 指向的 same 数组。

写作

schema2 = schema1[:]

实际上会通过复制schema1创建一个新列表。

【讨论】:

    【解决方案3】:

    以上两个答案都是正确的,但不是做 schema1[:] 你可以做

    from copy import copy
    schema2 = copy(scheme1)
    

    这使得它更具可读性并且可以与其他对象一起使用,例如 dict

    【讨论】:

      【解决方案4】:

      当您将一个对象分配给一个变量时,您就是将该名称绑定到该对象。如果您随后将该变量设置为另一个变量,则第二个变量名称将绑定到原始对象。

      schema1 = SomeClass.someSchema
      schema2 = schema1
      

      在本例中,schema1 和 schema2 绑定到同一个对象。您可以使用 python copy 库,或者如果您正在使用的类接受该类的对象作为构造函数中的参数,您可以通过这种方式创建一个新对象。例如,如果您要复制 dict,您可以这样做:

      from copy import copy
      schema1 = { 'foo': 'bar' }
      schema2 = copy(schema1)
      

      schema1 = { 'foo' : 'bar' }
      schema2 = dict(schema1)
      

      名称绑定在python的执行模型中谈到。 https://docs.python.org/3/reference/executionmodel.html

      如果您想了解更多信息,这可能是一个好的开始:https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

      【讨论】:

        猜你喜欢
        • 2018-07-06
        • 1970-01-01
        • 1970-01-01
        • 2019-12-09
        • 1970-01-01
        • 2012-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多