Python访问ListNode对象属性必须先判空?无判空报错但判空后正常的原因(含try-except相关疑问)
Python访问ListNode对象属性必须先判空?无判空报错但判空后正常的原因(含try-except相关疑问)
兄弟,我来给你把这个问题掰碎了说清楚!
一、核心原因:测试用例的差异(你自己后来的编辑已经点出关键啦)
你遇到的第一个问题,本质是你在不同测试用例下的nextNode状态完全不一样:
- 你之前看到的
print(l1.nextNode)输出ListNode{val:4,...},是有多个节点的测试用例,这时候nextNode = l1.next是有效的ListNode实例,直接访问val完全没问题; - 但当你跑只有1个节点的测试用例时,这个节点的
next属性本身就是None,此时nextNode = l1.next就是NoneType对象,你直接访问nextNode.val自然会报AttributeError——因为None根本没有val这个属性。
那为什么加了判空就正常?
很简单:当nextNode是None时,if nextNode is not None的条件不成立,会走else分支,不会去执行print(nextNode.val),自然就不会触发错误;当nextNode有效时,正常打印val。你之前觉得“else语句从来没执行过”,是因为你当时测试的是有效节点的用例,但报错那次的用例刚好是nextNode为None的情况!
二、关于try-except的两个代码差异
为什么第一个try-except会失败?
看你的代码:
try: print("try block executed") print(nextNode.val) except: print("except block executed1") print(nextNode.val) # 这里又踩坑了! if nextNode is not None: print("except block executed2") print(nextNode.val) else: print("Node is None")
触发except块的原因就是nextNode是None,结果你在except里又直接执行print(nextNode.val),相当于在异常处理代码里再次触发了同样的AttributeError,而且这个新错误没有被处理,所以整个代码还是会崩溃。
为什么第二个try-except能正常工作?
第二个代码的except块里,你先做了判空检查:
try: print("try block executed") print(nextNode.val) except: if nextNode is not None: print("except block executed") print(nextNode.val) else: print("Node is None")
触发except后,你先判断nextNode是不是None,再决定要不要访问val,不会再触发新的异常,所以整个流程能跑完,不会报错。
总结一下
- 直接访问
val报错,是因为特定测试用例下nextNode为None,你之前看到的有效节点是另一个用例的情况; - 判空代码能工作,是因为它避开了
None时访问val的危险操作; - 第一个try-except失败,是因为你在异常块里又重复踩了同样的坑;第二个try-except成功,是因为你在异常块里先做了判空,没再触发新错误。
备注:内容来源于stack exchange,提问作者Yanal Nasir
相关产品推荐
相关产品推荐

