CS61A学习杂记02

A Way To Keep Track Of The Information Used Before

在做第一个 project:Hog 的时候看到的一个小细节,也算是没见过的一点新东西吧。
先上代码

代码

def announce_lead_changes(prev_leader=None):
    """Return a commentary function that announces lead changes.

    >>> f0 = announce_lead_changes()
    >>> f1 = f0(5, 0)
    Player 0 takes the lead by 5
    >>> f2 = f1(5, 12)
    Player 1 takes the lead by 7
    >>> f3 = f2(8, 12)
    >>> f4 = f3(8, 13)
    >>> f5 = f4(15, 13)
    Player 0 takes the lead by 2
    """
    def say(score0, score1):
        if score0 > score1:
            leader = 0
        elif score1 > score0:
            leader = 1
        else:
            leader = None
        if leader != None and leader != prev_leader:
            print('Player', leader, 'takes the lead by', abs(score0 - score1))
        return announce_lead_changes(leader)
    return say

这个函数的作用是在每次 leader 改变时 announce 一下,因此需要 keep track of previous leader。在每个 turn 结束的时候都会调用一个 say 函数,来看看 leader 是否改变并据当前局面看是否 announce leader改变。实现keep track of previous leader 的机制大概是这样:首先在游戏开始之前需要先调用一次这个 announce 函数,获得一个 初始的 say 函数,在游戏循环中,每次调用 say 函数,在 say 函数体执行完之后,在 return 语句里面调用了一次 announce 函数,传入的参数是当前判断出的 leader,然后 announce 函数开始执行,首先是 leader 的值与形参 prev_leader 绑定,然后执行函数体,也就是那个 def 语句。根据 python 的特性,def 只会在 announce 的 frame 里面创建一个 name,并把它和函数体绑定,然后就执行 return 把这个 say 传出去。下次在调用 say 的时候,由于这个 say 的 frame 是 followed by the frame of announce_lead_change,因此它能访问到 prev_leader,这样就实现了 keep track of the previous leader。

上一篇:装饰模式


下一篇:【LeetCode】38. count-and-say