이전 블로그에서 구현한 make_averager()는 그리 효율적이지 않고, 우리는 모든 값을 series에 저장하고 average()가 호출될 때마다 sum을 계산했다. 합계와 항목 수를 저장한 후 이 두 개의 숫자를 이용해서 평균을 구하면 훨씬 더 효율적으로 구현할 수 있습니다.
# 전체 이력을 유지하지 않고 이동 평균을 계산하는 잘못된 고위 함수
def make_averager():
count = 0
total = 0
def averager(new_value):
count +=1
total += new_value
return total / count
return averager
avg = make_averager()
avg(10)
count가 수치형이거나 어떤 가변형일 때 count +=1을 의미하기 때문에 문체가 발생하므로 averager() 본체 안에서 count 변수에 할당하므로 count를 지역변수로 만든다.
근본적인 해결책은 nonlocal선언으로 변수를 nonlocal로 선언하면 함수 안에서 변수에 새로운 값을 할당해도 자유 변수임으로 새로운 값을 nonlocal 변수에 할당하면 클로저에 저장된 바인딩이 변경된다.
#전체 이력을 유지하지 않고 이동 평균 계산(nonlocal로 수정)
def make_averager():
count = 0
total = 0
def averager(new_value):
nonlocal count, total
count +=1
total += new_value
return total / count
return averager