How nonlocal keyword works?
Question:
In the below code,
def makeAverage():
series = []
def average(newValue):
series.append(newValue)
total = sum(series)
return total/len(series)
return average
python interpreter does not expect series
to be nonlocal
in average()
.
But in the below code
def makeAverage():
count = 0
total = 0
def average(newValue):
nonlocal count, total
count += 1
total += newValue
return total/count
return average
Question:
Why python interpreter expects count
& total
declared nonlocal
in average()
?
Answers:
A variable is considered local to a function if you assign to it anywhere in that function and you don’t mark it otherwise (with global
or nonlocal
). In your first example, there is no assignment to series
inside average
, so it is not considered local to average
, so the version from the enclosing function is used. In the second example, there are assignments to total
and count
inside average
, so they need to be marked nonlocal
to access them from the enclosing function. (Otherwise you will get an UnboundLocalError because average
tries to read their values before assigning to them for the first time.)
In the below code,
def makeAverage():
series = []
def average(newValue):
series.append(newValue)
total = sum(series)
return total/len(series)
return average
python interpreter does not expect series
to be nonlocal
in average()
.
But in the below code
def makeAverage():
count = 0
total = 0
def average(newValue):
nonlocal count, total
count += 1
total += newValue
return total/count
return average
Question:
Why python interpreter expects count
& total
declared nonlocal
in average()
?
A variable is considered local to a function if you assign to it anywhere in that function and you don’t mark it otherwise (with global
or nonlocal
). In your first example, there is no assignment to series
inside average
, so it is not considered local to average
, so the version from the enclosing function is used. In the second example, there are assignments to total
and count
inside average
, so they need to be marked nonlocal
to access them from the enclosing function. (Otherwise you will get an UnboundLocalError because average
tries to read their values before assigning to them for the first time.)