Python中堆栈的消息传递
通过使用消息传递来完成代码,这样可以
s = make_stack()
print(s("is_empty")) # True
s("push")(1)
s("push")(2)
print(s("peek")) # [2]
print(str(s("pop"))) # [2]
我的代码应该填补以下空白
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":
# blank #
elif msg == "clear":
# blank #
elif msg == "peek":
# blank #
elif msg == "push":
# blank #
elif msg == "pop":
# blank #
else:
raise Exception("stack doesn't" + msg)
return oplookup
我不太明白代码的追踪过程。我的试验代码是
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":=
return True
elif msg == "clear":
return []
elif msg == "peek":
return make_stack.items[-1]
elif msg == "push":
return items.append(msg)
elif msg == "pop":
return items.pop()
else:
raise Exception("stack doesn't" + msg)
return oplookup
另一个问题是,对于s("push") (1),(1)这个参数应该是什么?是msg还是item?
1 个回答
1
我觉得你遇到的第一个问题是,你需要从 oplookup
返回一个可以调用的东西,可能是一个函数。这些函数需要操作(或者测试)items
列表(它们可以访问这个列表,因为它们是闭包)。
下面是这个代码可能的样子:
def make_stack():
items = []
def oplookup(msg):
if msg == "is_empty":
def empty():
return not items
return empty
elif msg == "clear":
def clear():
items[:] = [] # slice assignment, to clear in-place
return clear
#...
注意,在 clear
函数中,我避免直接给 items
赋值,因为它在外部作用域。在 Python 2 中,重新赋值 items
是不可能的,因为它既不是局部变量也不是全局变量。在 Python 3 中,可以使用 nonlocal
关键字来重新赋值。由于我不知道你使用的是哪个版本的 Python,所以我用了切片赋值,这在两个版本中都能用。
这种代码风格不是很符合 Python 的习惯。更自然的做法是创建一个类,并在其中定义方法(但这样你会得到一个稍微不同的接口):
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return not self.items
def clear(self):
self.items = [] # this time we can replace the list
def push(self, item):
self.items.append(item)
#...