让我们看一个实际的例子。
假设我们正在为游戏编写菜单导航。我们要为每个菜单项存储
- 条目的名称
- 按下后我们将到达的另一个菜单。
- 按下菜单时将执行的操作。
当一个菜单项被按下时,我们将激活菜单项动作,然后移动到下一个菜单。所以我们的菜单将是一个简单的字典列表,如下所示:
options,start_menu,about = [],[],[]
def do_nothing(): pass
about += [
{'name':"copyright by...",'action':None,'menu':about},
{'name':"back",'action':do_nothing,'menu':start_menu}
]
options += [
{'name':"volume up",'action':volumeUp,'menu':options},
{'name':"save",'action':save,'menu':start_menu},
{'name':"back without save",'action':do_nothing,'menu':start_menu}
]
start_menu += [
{'name':"Exit",'action':f,'menu':None}, # no next menu since we quite
{'name':"Options",'action':do_nothing,'menu':options},
{'name':"About",'action':do_nothing,'menu':about}
]
看看如何about
循环:
>>> print about
[{'action': None, 'menu': [...], 'name': 'copyright by...'},#etc.
# see the ellipsis (...)
当按下菜单项时,我们将发出以下点击功能:
def menu_item_pressed(item):
log("menu item '%s' pressed" % item['name'])
item['action']()
set_next_menu(item['menu'])
现在,如果我们没有循环数据结构,我们将无法拥有指向自身的菜单项,例如,在按下音量增大功能后,我们将不得不离开选项菜单。
如果循环数据结构不可能,我们必须自己实现它,例如菜单项是:
class SelfReferenceMarkerClass: pass
#singleton global marker for self reference
SelfReferenceMarker = SelfReferenceMarkerClass()
about += [
{'name':"copyright by...",'action':None,'menu':srm},
{'name':"back",'action':do_nothing,'menu':start_menu}
]
该menu_item_pressed
功能将是:
def menu_item_pressed(item):
item['action']()
if (item['menu'] == SelfReferenceMarker):
set_next_menu(get_previous_menu())
else:
set_next_menu(item['menu'])
第一个例子更好一点,但是是的,不支持自我引用并不是什么大不了的恕我直言,因为很容易克服这个限制。
菜单示例就像一个带有自引用的图,我们通过顶点指针列表存储图(每个顶点都是指向其他顶点的指针列表)。在这个例子中,我们需要自边(一个指向自身的顶点),因此 python 对循环数据结构的支持很有用。