为什么在同一行中声明的两个类对象指向一个对象?



我将两个ListNode对象声明为head = curr = ListNode(0)。现在,令我惊讶的是,他们都指向同一个地址:

>>> head
<__main__.ListNode object at 0x10bf271d0>
>>> curr
<__main__.ListNode object at 0x10bf271d0>

为什么? 为什么不像a = b = 4

因为,如果我对b进行更改,a不会受到影响。但是,如果我通过以下方式对curr进行更改,head可以对其进行跟踪:

>>> curr.next = ListNode(1)
>>> curr = curr.next
>>> head
<__main__.ListNode object at 0x10bf271d0>
>>> curr
<__main__.ListNode object at 0x10bf27190>
>>> head.next
<__main__.ListNode object at 0x10bf27190>

我知道headcurr是通过引用指针(地址(来声明的,ab是通过引用值来声明的。是吗?

如果是,我如何控制用 ref 到 value 声明的内容和用 ref 声明到指针(地址(的内容?

上面使用的ListNode类如下:

>>> class ListNode(object):
...     def __init__(self, x):
...         self.val = x
...         self.next = None
...

编辑:解释这个问题与可变v/s不可变不可变与可变类型有何不同。

这个问题解决了变量的绑定和引用,而另一个问题严格讨论了Python中的可变和不可变对象及其差异。虽然后者确实讲述了变量的引用以解释可变与不可变,但它并没有解决这个问题中提出的疑问,因此,对于社区来说,那些困惑的观察者会知道由于这个问题而引用的概念。

python 中的整数是不可变的。当您执行以下操作时:

a = b = 4
a = a + 1

在这种情况下,ab是独立的,因为一旦你尝试改变a,你实际上是在将一个新的int对象绑定到a。您实际上永远不会更改整数,只是重新绑定。

当您执行以下操作时:

head = curr = ListNode(0)

创建一个ListNode对象,并将引用headcurr绑定到该对象。它们都指向内存中的同一位置,就像整数一样。但是,由于您的类是可变的,因此在发生突变时没有理由重新绑定。这是预期行为。

编辑 - 只是为了使整数不变性和重新绑定更清晰一点:

a = b = 4
print(f"ID of 'a': {id(a)}")
print(f"ID of 'b': {id(b)}")
a += 1
print("nAfter adding +1 to 'a'...")
print(f"ID of 'a': {id(a)}")
print(f"ID of 'b': {id(b)}")

输出:

ID of 'a': 1853646048
ID of 'b': 1853646048
After adding +1 to 'a'...
ID of 'a': 1853646064
ID of 'b': 1853646048

您可以看到,尝试改变a不会更改基础整数对象 - 它只是将a重新绑定到新的整数对象。

为什么

不像a = b = 4

相反。就像它一样

a = b = 4
print(id(a))
# 4552081648
print(id(b))
# 4552081648

因为,如果我对b进行更改,a不会受到影响。但是,如果我通过以下方式对curr进行更改,head可以跟踪它:

通过重新分配b来更改它,从而将名称重新绑定到新值:

b = 5
print(id(b))
# 4552081680

然而,在你修改curr时,你没有重新绑定curr所以它一直引用相同的值。

与常见的误解相反,这与不变性无关:您当然可以将名称重新绑定到可变值:

head = curr = ListNode(0)
head = ListNode(0)
head
# <__main__.ListNode at 0x10bf27118>
curr
# <__main__.ListNode at 0x10bf271d0>

。如您所见,headcurr现在引用不同的值。

相关内容

  • 没有找到相关文章

最新更新