如果两个变量指向同一个对象,为什么重新分配一个变量不会影响另一个? [英] If two variables point to the same object, why doesn't reassigning one variable affect the other?

查看:49
本文介绍了如果两个变量指向同一个对象,为什么重新分配一个变量不会影响另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解变量在 Python 中的工作原理.假设我有一个对象存储在变量 a 中:

<预><代码>>>>a = [1, 2, 3]

如果我将 a 赋值给 b,它们都指向同一个对象:

<预><代码>>>>b = a>>>b 是一个真的

但是如果我重新分配 ab,那将不再正确:

<预><代码>>>>a = {'x':'y'}>>>a 是 b错误的

两个变量现在有不同的值:

<预><代码>>>>一种{'x':'y'}>>>乙[1, 2, 3]

我不明白为什么变量现在不同了.为什么 a is b 不再正确?有人能解释一下这是怎么回事吗?

解决方案

Python 有 名称 引用 对象.对象与名称分开存在,名称与其所指的对象分开存在.

# 命名一个一 = 1337# 对象 1337

当为名称分配名称"时,右侧被评估到所引用的对象.与 2 + 2 计算结果为 4 类似,a 计算结果为原始 1337.

# 名称 bb = a# 引用的对象 ->1337

此时,我们有 a ->1337b ->1337 - 注意两个名字都不认识!如果我们测试a is b,两个名字都求值到同一个对象,这显然是相等的.

重新分配名称只会更改该名称所指的内容 - 其他名称也无法更改.

# name a - 重新分配一 = 9001# 对象 9001

此时,我们有 a ->9001b ->1337.如果我们现在测试 a is b,两个名称都会评估到不同的对象,这些对象不相同.

<小时>

如果您来自诸如 C 之类的语言,那么您将习惯于包含值的变量.例如,char a = 12 可以读作a 是包含12 的内存区域".最重要的是,您可以让多个变量使用相同的内存.为变量分配另一个值会更改共享内存的内容 - 从而更改两个变量的值.

+- 字符 a -+|12 |+--char b -+# a = -128+- 字符 -+|-128 |+--char b -+

这不是 Python 的工作方式:名称不包含任何内容,而是引用单独的值.例如,a = 12 可以读作a 是引用值 12 的名称".最重要的是,您可以有多个名称引用同一个值 - 但它仍然是单独的名称,每个名称都有自己的引用.为名称分配另一个值会更改该名称的引用 - 但不会更改其他名称的引用.

+- 命名一个 -+ -\\-->+- 12---+/|12 |+- 名称 b -+ -/+----------+# a = -128+- <-128>-++- 命名一个 -+ ----->|-128 |+-----------++- 12---++- 姓名 b -+ ----->|12 |+-----------+

<小时>

一个令人困惑的地方是可变对象似乎违反了名称和对象的分离.通常,这些是容器(例如 listdict、...)和类在默认情况下表现出相同的行为.

# name m米 = [1337]# 对象 [1337]# 名字 nn = 米# m 引用的对象

类似于普通整数1337,一个包含整数[1337]的列表是一个可以被多个引用的对象,独立名称.如上,n is m 计算结果为 True 并且 m = [9001] 不会改变 n.>

但是,对名称的某些操作会更改名称​​和所有别名所看到的值.

# 就地添加到 m米 += [9001]

经过这个操作,m == [1337, 9001] and n is m 仍然成立.其实n看到的值也变成了[1337, 9001].这似乎违反了上述行为,其中别名不会相互影响.

这是因为 m += [9001] 没有改变 m 所指的内容.它只改变m(以及别名n)引用的列​​表的content.mn 仍然指向原始列表对象,其 value 已更改.

+- 名称 m -+ -\\-->+- […] -+ +--- <@0>-+/|@0 |->|第1337章+- 名称 n -+ -/+-------+ +----------+# m += [9001]+- 名称 m -+ -\\-->+- […] -+ +--- <@0>-++--- <@1>-+/|@0 @1 |->|第1337章9001 |+- 姓名 n -+ -/+-------+ +----------++----------+

I am trying to understand how variables work in python. Say I have an object stored in the variable a:

>>> a = [1, 2, 3]

If I assign a to b, both point to the same object:

>>> b = a
>>> b is a
True

But if I reassign a or b, that's no longer true:

>>> a = {'x': 'y'}
>>> a is b
False

The two variables now have different values:

>>> a
{'x': 'y'}
>>> b
[1, 2, 3]

I don't understand why the variables are different now. Why is a is b no longer true? Can someone explain what's going on?

解决方案

Python has names which refer to objects. Objects exist separately from names, and names exist separately from the objects they refer to.

# name a
a = 1337
    # object 1337

When assigning "a name to a name", the right-hand side is evaluated to the referred to object. Similar to how 2 + 2 evaluates to 4, a evaluates to the original 1337.

# name b
b = a
    # object referred to by a -> 1337

At this point, we have a -> 1337 and b -> 1337 - note that neither name knows the other! If we test a is b, both names are evaluated to the same object which is obviously equal.

Reassigning a name only changes what that name refers to - there is no connection by which other names could be changed as well.

# name a - reassign
a = 9001
  # object 9001

At this point, we have a -> 9001 and b -> 1337. If we now test a is b, both names are evaluated to different objects which are not the same.


If you come from languages such as C, then you are used to variables containing values. For example, char a = 12 can be read as "a is a memory region containing 12". On top, you can have several variables use the same memory. Assigning another value to a variable changes the content of the shared memory - and therefore the value of both variables.

+- char a -+
|       12 |
+--char b -+

# a = -128

+- char a -+
|     -128 |
+--char b -+

This is not how Python works: names do not contain anything, but refer to separate values. For example, a = 12 can be read as "a is a name which refers to the value 12". On top, you can have several names refer to the same value - but it will still be separate names, each with its own reference. Assigning another value to a name changes the reference of that name - but leaves the reference of the other name untouched.

+- name a -+ -\
               \
                --> +- <12> ---+
               /    |       12 |
+- name b -+ -/     +----------+

# a = -128
                    +- <-128> -+
+- name a -+ -----> |     -128 |
                    +----------+

                    +- <12> ---+
+- name b -+ -----> |       12 |
                    +----------+


A point of confusion is that mutable objects can appear to violate the separation of names and objects. Commonly, these are containers (e.g list, dict, ...) and classes exhibit the same behaviour by default.

# name m
m = [1337]
    # object [1337]
# name n
n = m
    # object referred to by m

Similar to a plain integer 1337, a list containing an integer [1337] is an object that can be referred to by several, independent names. As above, n is m evaluates to True and m = [9001] does not change n.

However, certain operations on a name change the value seen by the name and all aliases.

# inplace add to m
m += [9001]

After this operation, m == [1337, 9001] and n is m still holds true. In fact, the value seen by n has also changed to [1337, 9001]. This appears to violate above behaviour, in which aliases did not influence each other.

This is because m += [9001] did not change what m refers to. It only change the content of the list that m (and the alias n) referred to. Both m and n still refer to the original list object, whose value was changed.

+- name m -+ -\
               \                  
                --> +- […] -+     +--- <@0> -+
               /    |    @0 |  -> |     1337 |
+- name n -+ -/     +-------+     +----------+

# m += [9001]

+- name m -+ -\
               \                  
                --> +- […] -+     +--- <@0> -++--- <@1> -+
               /    | @0 @1 |  -> |     1337 ||     9001 |
+- name n -+ -/     +-------+     +----------++----------+

这篇关于如果两个变量指向同一个对象,为什么重新分配一个变量不会影响另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆