You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python双向链表实现报错AttributeError: 'NoneType'无'next'属性求助

双向链表__str__方法的AttributeError问题解析

问题重现

我实现了一个简单的双向链表,包含append方法和用于返回链表元素的__str__方法,代码如下:

class Node:
    def __init__(self,val):
        self.next = None 
        self.prev = None 
        self.val = val
    def __str__(self):
        return self.val

class dll:
    def __init__(self):
        self.head = None 
        self.tail = None 
        self.length = 0

def append(self,val):
    new = Node(val)
    if not self.head:
        self.head = new 
        self.tail = new 
    else:
        new.prev = self.tail 
        self.tail.next = new
        self.tail = new 
    self.length += 1

def __str__(self):
    curr = self.head 
    res = str()
    if not self.head:
        return("Linked list is empty")
    while curr:
        res += str(curr.val) + ' <-> '
        curr = curr.next 
        if curr.next is not None:
            res += ' <-> '
    return res


ll = dll()
print(ll)
ll.append(10)
ll.append(30)
print(ll)

运行时触发错误:AttributeError: 'NoneType' object has no attribute 'next',移除__str__方法中的if curr.next is not None:条件后代码可正常运行,请问问题出在哪?

错误原因

核心问题出在__str__方法的循环逻辑顺序:

  • 循环内先执行curr = curr.next,当curr遍历到链表最后一个节点的next(也就是None)时,后续代码尝试访问curr.next,本质是访问None.next,直接触发AttributeError。
  • 以链表有两个节点(10、30)为例:
    1. 第一次循环:curr指向10节点,拼接字符串后curr变为30节点,此时curr.next是None,条件不成立,不会额外拼接;
    2. 第二次循环:curr指向30节点,拼接字符串后curr变为None,此时执行if curr.next is not None:,直接尝试访问None.next,触发报错。

另外还要注意:原代码中append和__str__方法没有缩进在dll类内部,这会导致调用方法时找不到属性,属于代码格式错误。

修正方案

方案1:调整判断时机(在移动curr前检查)

修改__str__方法,在移动curr之前判断是否还有下一个节点,避免访问None的属性:

class dll:
    def __init__(self):
        self.head = None 
        self.tail = None 
        self.length = 0

    def append(self,val):
        new = Node(val)
        if not self.head:
            self.head = new 
            self.tail = new 
        else:
            new.prev = self.tail 
            self.tail.next = new
            self.tail = new 
        self.length += 1

    def __str__(self):
        curr = self.head 
        res = str()
        if not self.head:
            return "Linked list is empty"
        while curr:
            res += str(curr.val)
            # 只有当前节点有下一个节点时,才添加分隔符
            if curr.next is not None:
                res += ' <-> '
            curr = curr.next 
        return res

方案2:收集节点值后用分隔符连接(更简洁)

先遍历收集所有节点的字符串值,再用<->连接,避免循环中的逻辑混乱:

class dll:
    def __init__(self):
        self.head = None 
        self.tail = None 
        self.length = 0

    def append(self,val):
        new = Node(val)
        if not self.head:
            self.head = new 
            self.tail = new 
        else:
            new.prev = self.tail 
            self.tail.next = new
            self.tail = new 
        self.length += 1

    def __str__(self):
        if not self.head:
            return "Linked list is empty"
        curr = self.head
        node_values = []
        while curr:
            node_values.append(str(curr.val))
            curr = curr.next
        return ' <-> '.join(node_values)

内容的提问来源于stack exchange,提问作者NK Rao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:42:05