今天仍然进行自己hog项目。
项目要求是输出某一玩家的最大增量。
自己编写代码如下:
def announce_highest(who, prev_high=0, prev_score=0):
assert who == 0 or who == 1, 'The who argument should indicate a player.'
def say0(score0, score1):
nonlocal prev_high
nonlocal prev_score
cur_gain = score0 - prev_score #求出当前分和前一轮分的增量
if cur_gain > prev_high:
print(str(cur_gain)+" point(s)! That's the biggest gain yet for Player 0")
prev_high = cur_gain
prev_score = score0
return announce_highest(who, prev_high, prev_score)
return say0
结果没有通过测试:
这个测试输入为who = 1时,即每次传递的第二个值
可以看到最后,测试f2_again = f1(11, 9)
这行代码的目的是更改某一轮的分数,函数仍然起作用,输出应该是9。然而我的代码却没有输出。
在自己的端口跑了一下
应该输出5,7,6,但是确实没有6输出
将最后一行的f1 改成 f0 发现输出6
由此可以得知,是函数内部框架错位。
在pythontutor上跑了一下,发现执行h1时(即之前代码中的f1),其框架下prev_high和prev_score的值改变。
这里与期望不符,因为希望say函数只读,而不改变这两个局部变量。
正是由于上一次调用h1,使得prev_high=5而prev_score=12,下一次调用时,cur_gain为-1,自然不能输出。
原来自己函数中
nonlocal prev_high
nonlocal prev_score
将这两个变量和announce_highest内变量绑定,自然牵一发动全身。
最终我一个朋友告诉我,要设定两个新的量new_score,new_high,使得say内部只读取不改变,由此解决了这个问题。
再次运行f1内部的prev_high和prev_score仍为5,5,可以实现插入更新。
def announce_highest(who, prev_high=0, prev_score=0):
assert who == 0 or who == 1, 'The who argument should indicate a player.'
def say0(score0, score1):
cur_gain = score0 - prev_score
if cur_gain > prev_high:
print(str(cur_gain)+" point(s)! That's the biggest gain yet for Player 0")
new_high = cur_gain
new_score = score0
return announce_highest(who, new_high, new_score)
return say0
f0 = announce_highest(0)
f1 = f0(5,0)
f2 = f1(12,5)
f2_again = f1(11,9)