这里有几个问题:
queue
仅仅指代你的类,并不是实例属性的同名变量 self.queue
。你必须一直使用 self.
,最好给类和它的属性取不同的名称以避免混淆。(使用PEP 8风格来命名类, 把类名改为 Queue
也是有帮助的)
- 当队列非空时,你计算出返回值
e
,但你却从未使用 return
返回它;而是掉到函数结束后,自动返回None
。
list[1:len(queue)]
尝试对 list
类型进行切片,而不是你的实际列表 (self.queue
)。你想要的是 self.queue[1:len(queue)]
。
- 你可能不想在出错时返回字符串——因为字符串完全可以作为放入队列的一个有效对象——这正是异常的用途所在。
__init__
接收了一个参数,但从未使用过。你可能想要使用这个参数作为队列内容的起始值,同时你也可能想将其设置成可选的。
list.insert
函数的第一个参数不应该是一个类似于 [-1]
的列表,而应该是索引,如 -1
。
- 如果这是 Python 2.x,则不应创建经典类; 如果没有其他要继承的内容,则继承自 `object`。
- 看起来你可能混合了制表符和空格进行缩进,不要这样做。
此外,有一些事情可以更简单:
- 如果你想切片到列表的末尾,只需要省略结尾即可,例如使用
self.queue[1:]
,而不是使用 len(self.queue)
。
- 为了更简单地从列表左侧获取并移除一个值,可以使用
pop(0)
。
- 要在列表的右侧添加一个值,可以使用
append
。
- 要检查一个列表是否非空,只需执行
if the_list
,而不是 if len(the_list) > 0
。空集合总是falsey,非空集合为true。
- 但实际上你根本不需要进行检查——如果列表为空,
pop
将会引发一个异常,这正是你想要的。
所以:
class Queue(object):
def __init__(self, queue=None):
if queue is None:
self.queue = []
else:
self.queue = list(queue)
def dequeue(self):
return self.queue.pop(0)
def enqueue(self, element):
self.queue.append(element)
如果您想要自定义异常消息,例如将IndexError: pop from empty list
更改为IndexError: dequeue from empty Queue
,您可以使用try
语句实现:
def dequeue(self):
try:
return self.queue.pop(0)
except IndexError:
raise IndexError('dequeue from empty Queue')
如果你想要测试你的队列类是否正常工作,需要编写测试函数并调用它们。例如:
def test_queue():
q = Queue()
for i in range(10):
q.enqueue(i)
for i in range(10):
value = q.dequeue()
if value != i:
print('Value #{} should be {} but is {}'.format(i, i, value))
try:
value = q.dequeue()
except IndexError:
pass
else:
print('#10 should raise an IndexError, but got {}'.format(value))
if __name__ == '__main__':
test_queue()
现在您只需将该文件作为脚本运行即可运行您的测试。
在实际情况中,您需要考虑更完整的测试,覆盖所有您能想到的奇怪边缘情况。您可能还需要使用unittest
库或像nose
这样的第三方解决方案来组织和简化您的测试。
self.queue
- 例如,e = queue[0]
应为e = self.queue[0]
。 - Tomcollections.deque
而不是编写自己的代码。它是用C实现的(因此非常快),并经过多年的测试(因此不太可能遇到任何错误)。 - Blckknght