假定你在编写一个交通信号灯的模拟程序。代表路口信号灯的数据结构是一个
字典,以 '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)
你可能已经发现了这段代码的问题,但假设你编写了剩下的模拟代码,有几千行,但没有注意到这个问题。当最后运行时,程序没有崩溃,但虚拟的汽车撞车了!
因为你已经编写了剩下的程序,所以不知道缺陷在哪里。也许在模拟汽车的代码中, 或者在模拟司机的代码中。可能需要花几个小时追踪缺陷, 才能找到 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➊。虽然程序崩溃并非如你所愿,但它马上指出了心智正常检查失败:两个方向都没有红灯,这意味着两个方向的车都可以走。在程序执行中尽早快速
失败,可以省去将来大量的调试工作。