如何修复'NoneType'尝试将键值与字符串进行比较时没有属性"键"



我正在编写一个程序,用户在其中输入一个后缀表达式并输出答案。Current在for循环中使用"evaluate"函数时,我被卡住了。

Inside my For loop Main.py:

else:
# Debug Code
print('{}: Else'.format(i))
print('{}: Length'.format(len(stack)))
Node.right = stack.pop()
Node.left = stack.pop()
Node = TreeNode(str(i))
stack.push(str(i))
# Debug Code
print('{}: Right Key'.format(Node.right))
print('{}: Left Key'.format(Node.left))
print('{}: Node Key'.format(Node.key))
print('{}: Node Key Type'.format(type(Node.key)))
Node = evaluate(Node)
stack.push(int(Node))

我得到以下错误:

Traceback (most recent call last):
File "c:Usersdpr48main.py", line 49, in <module>
Node = evaluate(Node)
File "c:Usersdpr48main.py", line 10, in evaluate
return evaluate(node.left) + evaluate(node.right)
File "c:Usersdpr48main.py", line 9, in evaluate
if node.key == '+':
AttributeError: 'NoneType' object has no attribute 'key'

所以我的问题是,为什么它不使用"TreeNode"类来获取键值?以及应该将"Node.left"定义为"stack.pop()"值和将"Node.right"定义为为"stack.prop())"值的代码行,它们最终都没有更改,并将它们保留为None,正如我在"调试代码"中发现的那样,我已经实现了该代码来查看程序的内部操作。

提供以下使用的每个类别:

主要.py

from Stack import Stack
from TreeNode import TreeNode
def evaluate(node):
if node.key == '+':
return evaluate(node.left) + evaluate(node.right)
elif node.key == '-':
return evaluate(node.left) - evaluate(node.right)
elif node.key == '*':
return evaluate(node.left) * evaluate(node.right)
elif node.key == '/':
return evaluate(node.left) / evaluate(node.right)
else:
return node.key
stack = Stack()
exp = "23+"
list = [*exp]
for i in list:
if i.isdigit() is True:
# Debug Code
print('{}: True'.format(i))
Node = TreeNode(int(i))
stack.push(int(i))
else:
# Debug Code
print('{}: Else'.format(i))
print('{}: Length'.format(len(stack)))
Node.right = stack.pop()
Node.left = stack.pop()
Node = TreeNode(str(i))
stack.push(str(i))
# Debug Code
print('{}: Right Key'.format(Node.right))
print('{}: Left Key'.format(Node.left))
print('{}: Node Key'.format(Node.key))
print('{}: Node Key Type'.format(type(Node.key)))
Node = evaluate(Node)
stack.push(int(Node))
print(evaluate(stack.node))

堆叠.py

from Node import Node
from LinkedList import LinkedList
class Stack:
def __init__(self):
self.list = LinkedList()

def push(self, new_item):
# Create a new node to hold the item
new_node = Node(new_item)

# Insert the node as the list head (top of stack)
self.list.prepend(new_node)
def pop(self):
# Copy data from list's head node (stack's top node)
popped_item = self.list.head.data

# Remove list head
self.list.remove_after(None)

# Return the popped item
return popped_item
def __len__(self):
node = self.list.head # Start at head of stack to count until stack returns Null
count = 0 
while node != None:
node = node.next
count+=1
return count # Returning length of stack

链接列表.py

class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def append(self, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
def prepend(self, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head = new_node
def insert_after(self, current_node, new_node):
if self.head == None:
self.head = new_node
self.tail = new_node
elif current_node is self.tail:
self.tail.next = new_node
self.tail = new_node
else:
new_node.next = current_node.next
current_node.next = new_node
def remove_after(self, current_node):
# Special case, remove head
if (current_node == None) and (self.head != None):
succeeding_node = self.head.next
self.head = succeeding_node  
if succeeding_node == None: # Remove last item
self.tail = None
elif current_node.next != None:
succeeding_node = current_node.next.next
current_node.next = succeeding_node
if succeeding_node == None: # Remove tail
self.tail = current_node

Node.py

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

树节点.py

class TreeNode:
# Constructor assigns the given key, with left and right
# children assigned with None.
def __init__(self, key):
self.key = key 
self.left = None
self.right = None

有几个问题:

  • Node是一个类的名称,但您对TreeNode实例使用相同的名称,从而隐藏类名。这不是主要问题,但肯定不是建议。相关:不要将PascalCase用于实例,而是使用camelCase。所以node,而不是Node

  • 当您还没有定义Node时,您可以分配给Node.right,这将在稍后的Node = TreeNode(str(i))中发生。您应该先分配给Node(更好的是node),然后再分配给它的属性。

  • 对于Node.right = stack.pop(),您显然希望堆栈包含TreeNode实例,但对于stack.push(str(i)),您需要字符串。这将导致你描述的问题。堆栈不应填充字符串,而应填充TreeNode对象。

  • else块的末尾,调用evaluate,然后将结果值推送到堆栈。这是错误的,应该删除。评估应该只在完成树时进行,而不应该涉及堆栈。堆栈在构建树中起作用,而不是评估树。

  • 最后一行print访问stack.node,但stack没有node属性。您将希望从堆栈中弹出顶部项,该项(如果输入语法正确)上应该只剩下1个节点,表示树的根。

  • 这不是问题,但i保证是一个字符串(长度为1),因此不需要对其调用str

这是更正后的代码:

for i in list:
if i.isdigit() is True:
node = TreeNode(int(i))  # lowercase name
stack.push(node)  # don't push string, but object
else:
node = TreeNode(i)  # First create the node
node.right = stack.pop()  # Then assign to its attributes
node.left = stack.pop()
stack.push(node)  # don't push string
# Don't evaluate here, nor push anything else to the stack

print(evaluate(stack.pop()))

最新更新