提问人:ViM 提问时间:8/25/2022 最后编辑:petezurichViM 更新时间:8/25/2022 访问量:141
如何定义自由变量
How to define a free variable
问:
我目前正在阅读 Fluent Python - Luciano Ramalho 一书(一本很棒的书 IMO)。
在有关装饰器和闭包的章节中,有一段代码:
def make_averager():
series = []
def averager(value):
series.append(value)
total = sum(series)
return total/len(series)
return averager
avg = make_averager()
所以在这种情况下,是一个自由变量,我可以通过打印来验证这一点series
>>> avg.__code__.co_varnames
('new_value', 'total')
>>> avg.__code__.co_freevars
('series',)
但是当我尝试重构:make_averager()
def make_averager():
series = []
total = 0
count = 0
def averager(value):
total += value
count += 1
return total/count
return averager
avg = make_averager()
要么 ,要么被视为free_variable。取而代之的是,现在是局部变量 (?),因为 returns 和 returns .series
total
sum
total
sum
avg.__code__.co_varnames
('value', 'total', 'count')
avg.__code__.co_freevars
()
所以现在不再是 范围内的自由变量,除非我添加series
averager
series.append(value)
里面。这是可以理解的,因为我根本没有在里面调用,但我无法理解这两个变量发生了什么。averager(value)
series
averager(value)
为什么 和 不被视为自由变量,如何将它们指定为自由变量?total
count
答:
1赞
SargeATM
8/25/2022
#1
非本地总计,计数
def averager(value):
nonlocal total
nonlocal count
total += value
count += 1
return total/count
为什么非局部变量使它们成为自由变量?
如果没有非局部变量,则默认为其创建局部变量。由于在函数的局部作用域内,它不再是一个自由变量。total += value
total
total
averager
评论
0赞
ViM
8/25/2022
感谢您提供这个简单的解决方案。但是您能解释一下为什么在第一种方法中被认为是 a,而在第二种方法中则不被认为是 a?series
nonlocal
total
sum
0赞
SargeATM
8/25/2022
从不赋值变量。(例如)翻译为查找变量持有的对象。是否在本地范围内?不。试试外部范围,是的。现在向 series 对象询问方法,以便我可以调用它。series
series = []
series.append
series
series
append
评论