05-在交通灯模拟中使用断言
在交通灯模拟中使用断言
假定你在编写一个交通信号灯的模拟程序。代表信号灯的数据结构是一个字典,以 'ns'
和 'ew'
为键,分别表示南北方向和东西方向的信号灯。这些键的值可以是 'green'
、 'yellow'
或 'red'
之一。代码看起来可能像这样:
market_2nd = {'ns': 'green', 'ew': 'red'}
mission_16th = {'ns': 'red', 'ew': 'green'}
这两个变量将针对Market街和第2街路口,以及Mission街和第16街路口。在项目启动之初,你希望编写一个 switchLights()
函数,它接收一个路口字典作为参数,并切换红绿灯。
开始你可能认为, switchLights()
只要将每一种灯按顺序切换到下一种颜色即可,即 'green'
应该切换到 'yellow'
, 'yellow'
应该切换到 'red'
, 'red'
应该切换到 'green'
。实现这个思想的代码看起来像这样:
def switchLights(stoplight):
for key in stoplight.keys():
if stoplight[key] == 'green':
stoplight[key] = 'yellow'
elif stoplight[key] == 'yellow':
stoplight[key] = 'red'
elif stoplight[key] == 'red':
stoplight[key] = 'green'
switchLights(market_2nd)
你可能已经发现了这段代码的问题,但假设你编写了剩余的模拟代码,有几千行,那么很可能没有注意到这个问题。当最后运行时,程序没有崩溃,但虚拟的汽车相撞了。
因为你已经编写了其余的程序,所以不知道bug在哪里。bug也许在模拟汽车的代码中,也许在模拟司机的代码中。可能需要花几小时追踪bug,才能找到 switchLights()
函数。
但如果在编写 switchLights()
时,你添加了断言,确保至少一个交通灯是红色,可能在函数的底部添加这样的代码:
assert 'red' in stoplight.values(), 'Neither light is red! ' + str(stoplight)
有了这个断言,程序就会崩溃,并提供这样的错误信息:
Traceback (most recent call last):
File "carSim.py", line 14, in <module>
switchLights(market_2nd)
File "carSim.py", line 13, in switchLights
assert 'red' in stoplight.values(), 'Neither light is red! ' +
str(stoplight)
❶ AssertionError: Neither light is red! {'ns': 'yellow', 'ew': 'green'}
这里比较重要的是 AssertionError
❶。虽然程序崩溃并非如你所愿,但它马上指出了健全性检查失败:两个方向都没有红灯,这意味着两个方向的车都可以走。在程序执行中尽早失败,可以省去将来大量的调试工作。