This is because method_1 gets its own local scope where it can declare variables. Python sees value = True and thinks that you are creating a new variable called value local to method_1 .
The reason Python does this is to avoid polluting the locales of the external visibility with variables from the internal function. (You do not want assignments in regular modular functions to produce global variables!)
If you do not assign a value , then Python searches for outside areas that look for the variable (so reading the variable works as expected, as shown in method_2 ).
One way around this is to use a mutable object instead of a link:
result = { 'value': False } def method_1(): result['value'] = True
In Python 3, a nonlocal (see also docs ) was added specifically for this scenario:
def method_1(): nonlocal value value = True
source share