为什么我们使用 self.head 而不仅仅是 class var head?

Why do we use self.head and not just class var head?

我对 python 中链表的实现有疑问。

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class SLL:
    head = None

    def insert_at_end(self, data):
        node = Node(data)
        if self.head == None:
            self.head = node
        else:
            t = self.head
            while t.next is not None:
                t = t.next
            t.next = node
    
    def display_all(self):
        if self.head == None:
            print(None)
        else:
            t = self.head
            while t is not None:
                print(t.data, end = ' ')
                t = t.next

if __name__ == '__main__':
    a = SLL()
    b = SLL()
    a.insert_at_end(2)
    b.insert_at_end(1)
    a.insert_at_end(4)
    b.insert_at_end(3)
    a.insert_at_end(6)
    b.insert_at_end(5)
    a.display_all()
    print()
    b.display_all()

代码在输出上运行良好...

2 4 6 
1 3 5 

我的问题是这和我在网上看到的实现有什么区别:

class SLL:
    def __init__(self):
        self.head = None

    def insert_at_end(self, data):
        node = Node(data)
        if self.head == None:
            self.head = node
        else:
            t = self.head
            while t.next is not None:
                t = t.next
            t.next = node
    
    def display_all(self):
        if self.head == None:
            print(None)
        else:
            t = self.head
            while t is not None:
                print(t.data, end = ' ')
                t = t.next

具体来说,我使用 class var 即 head 的实现与使用它作为构造函数中的实例 var 的其他实现有什么区别?

head = None` vs. `self.head = None

P.S。很抱歉,如果这个问题已经得到解答,我看了却找不到答案(甚至找不到答案)。

第一个版本定义了一个 class 属性。这意味着当实例 读取 self.head 时,它实际上读取 class 属性而不是实例属性(尚不存在)。结果是一样的:都是None.

您可以在 列表上看到差异,方法是在插入任何节点之前输出 a.__dict__。注意区别:第一个版本显示空字典,另一个显示 head 键。

然而,当代码继续并分配一个节点实例给self.head时,一个实例属性在两个代码中被定位版本。这意味着一旦插入第一个节点,第一个版本就开始表现为第二个版本。所有对 self.head 的后续引用都是对实例属性的引用,不再是 class 属性。

尝试输出a.__dict__ 第一个节点被添加到列表后,你现在在使用时也会看到head第一个实现。

因此在这个具体示例中,实际差异很小。 class 变量永远不会改变值:它仍然是 None,无论您创建了多少列表以及它们有多少节点。一旦实例添加了第一个节点,它就会开始使用自己的 head 属性。