我在循环中多次执行一个动作,想知道我有多远。我正在尝试制作一个应该采取以下行为的进度报告功能:
def make_progress_report(n):
i = 0
def progress_report():
i = i + 1
if i % n == 0:
print i
return progress_report
pr = make_progress_report(2)
pr()
pr() # 2
pr()
pr() # 4
此代码不起作用。具体来说,我为UnboundLocalError
获得i
。我应该如何修改它以使其有效?
答案 0 :(得分:3)
以下是3个选项:
使用您的柜台清单:
def make_progress_report(n):
i = [0]
def progress_report():
i[0] = i[0] + 1
if i[0] % n == 0:
print i[0]
return progress_report
使用itertools.count跟踪您的计数器:
from itertools import count
def make_progress_report(n):
i = count(1)
def progress_report():
cur = i.next()
if cur % n == 0:
print cur
return progress_report
将非本地用于您的计数器(仅限Python 3+):
def make_progress_report(n):
i = 0
def progress_report():
nonlocal i
i = i + 1
if i % n == 0:
print i
return progress_report
答案 1 :(得分:2)
您可以考虑使用生成器:
def progress_report(n):
i = 0
while 1:
i = i+1
if i % n == 0:
print i
yield # continue from here next time
pr = progress_report(2)
next(pr)
next(pr)
next(pr)
next(pr)
答案 2 :(得分:0)
再看看你如何定义你的闭包。在定义闭包时应该传入n ...采用以下示例:
#!/usr/env python
def progressReportGenerator(n):
def returnProgress(x):
if x%n == 0:
print "progress: %i" % x
return returnProgress
complete = False
i = 0 # counter
n = 2 # we want a progress report every 2 steps
getProgress = progressReportGenerator(n)
while not complete:
i+=1 # increment step counter
# your task code goes here..
getProgress(i) # how are we going?
if i == 20: # stop at some arbtirary point...
complete = True
print "task completed"
答案 3 :(得分:0)
所以progress_report没有关闭变量i。你可以这样检查......
>>> def make_progress_report(n):
... i=0
... def progress_report():
... i += 1
... if i % n == 0:
... print i
... return progress_report
...
>>> pr = make_progress_report(2)
>>> pr.__closure__
(<cell at 0x1004a5be8: int object at 0x100311ae0>,)
>>> pr.__closure__[0].cell_contents
2
你会注意到pr的关闭中只有一个项目。这是您最初传递给n
的值。 i
值不是闭包的一部分,因此在函数定义之外,i
不再在范围内。
以下是关于Python中闭包的一个很好的讨论:http://www.shutupandship.com/2012/01/python-closures-explained.html