On Python 3, use the nonlocal keyword:

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

def foo():
    a = 1
    def bar():
        nonlocal a
        a = 2
    bar()
    print(a)  # Output: 2

On Python 2, use a mutable object (like a list, or dict) and mutate the value instead of reassigning a variable:

def foo():
    a = []
    def bar():
        a.append(1)
    bar()
    bar()
    print a

foo()

Outputs:

[1, 1]
Answer from Adam Wagner on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › inner functions cannot access outer variable if it is primitive, why exactly is it like this?
r/learnpython on Reddit: Inner functions cannot access outer variable if it is primitive, why exactly is it like this?
November 26, 2021 -

Take this function as an example:

def foo(self, param1):

count = 0
buffer = []

def inner(x):

buffer.append(x + param1)
count += 1

inner(5)

So, the inner function can freely access param1 and buffer. However, it will complain about count, and in order to make it work, you need to declare "nonlocal count".

I was wondering why is this the case, how is the stack organized such that param1 and buffer is accessible without the need to declare nonlocal, but for count, it needs a nonlocal declaration? I'm guessing it has something to do with it being a primitive... but then again, so is param1

Discussions

How to change outer function local variables from an inner function in Python? - Stack Overflow
Possible Duplicate: Modify the function variables frominner function in python Say I have this python code def f(): x=2 def y(): x+=3 y() this raises: UnboundLocalError: l... More on stackoverflow.com
🌐 stackoverflow.com
Nested function has an issue with a variable
I’m messing around with making some art with Turtle Graphics, and I made a nested function with a variable to create a shape when it’s called. I first tried to create a variable and assign it a value of 60 in the function, and also tried moving it out of the function, as it keeps giving ... More on discuss.python.org
🌐 discuss.python.org
4
0
June 21, 2023
Modify the function variables from inner function in python - Stack Overflow
It's ok to get and print the outer function variable a def outer(): a = 1 def inner(): print a It's also ok to get the outer function array a and append something def outer(): ... More on stackoverflow.com
🌐 stackoverflow.com
scopes in nested functions
See here for how to format code on reddit: https://www.reddit.com/r/learnpython/wiki/faq#wiki_how_do_i_format_code.3F It is impossible to read your code without proper formatting, but this demonstrates how variables are found multiple levels of nesting: def foo(): """Outer Function.""" x = 10 y = 10 def nested(): """Function nested in foo().""" y = 100 def nested_in_nested(): """Function nested in nested().""" nonlocal x nonlocal y # Search 'up' the levels for x and y. print(f'In nested_in_nested(): {x=} {y=}') # Modify x and y x += 1 y += 1 # Cannot modify y # Call nested_in_nested() from inside nested(). nested_in_nested() print(f'In nested(): {x=} {y=}') # Call nested() from inside foo(). nested() print(f'In foo(): {x=} {y=}') x = 1 # Global foo() Which prints: In nested_in_nested(): x=10 y=100 In nested(): x=11 y=101 In foo(): x=11 y=10 In the first printed line: In nested_in_nested(), the variable y is found in nested(), so y=100 is printed. It is then incremented. The variable x is not found in nested(), so Python looks next in the enclosing function foo() and finds x there. x=10 is printed. It is then incremented The nonlocal keyword allows a function to modify variables from the nearest enclosing scope that is not global. y in the outer function foo() is not modified by y = 100 in nested() because y in nested() is local to nested(). In the second printed line, notice that 'y' from the local scope of nested() has been incremented to 101, and x from the outer scope foo() has been incremented to 11. In the third printed line, the local x has been incremented The local y has not been incremented because that was not the instance of y accessed by y += 1 in nested_in_nested(). DO NOT WRITE CODE LIKE THIS. Python emphasises readability and this kind of code is horrible to read. More on reddit.com
🌐 r/learnpython
5
2
May 22, 2024
🌐
Learn By Example
learnbyexample.org › python-variables-scope
Python Variables Scope - Learn By Example
April 20, 2020 - The x inside the function now refers to the x outside the function, so changing x inside the function changes the x outside it. Here’s another example that tries to update a global variable inside a function. x = 42 # global scope x def myfunc(): ...
🌐
Python.org
discuss.python.org › python help
Nested function has an issue with a variable - Python Help - Discussions on Python.org
June 21, 2023 - I’m messing around with making some art with Turtle Graphics, and I made a nested function with a variable to create a shape when it’s called. I first tried to create a variable and assign it a value of 60 in the function, and also tried moving it out of the function, as it keeps giving me the error “defined in enclosing scope referenced before assignment” and I don’t know why.
Find elsewhere
🌐
Stack Abuse
stackabuse.com › python-nested-functions
Python Nested Functions
December 21, 2018 - The inner function is able to access the variables that have been defined within the scope of the outer function, but it cannot change them. There are a number of reasons as to why we may need to create an inner function. For instance, an inner function is protected from what happens outside it.
🌐
Reddit
reddit.com › r/learnpython › scopes in nested functions
r/learnpython on Reddit: scopes in nested functions
May 22, 2024 -

Is there a command like global or nonlocal with which I can make x=10 in my_nested_nested_function?
With global x it gets 1, with nonlocal it gets 100. If i comment the line where I set x to 100 in my_nested_function then the print statement puts out 10 (Which would be a workaround). But is there a way if I had to use the variable in my_nested_function?

x = 1
def my_function():
x = 10
def my_nested_function():
x = 100
def my_nested_nested_function():
nonlocal x
print(x)
my_nested_nested_function()
my_nested_function()
my_function()

Top answer
1 of 4
2
See here for how to format code on reddit: https://www.reddit.com/r/learnpython/wiki/faq#wiki_how_do_i_format_code.3F It is impossible to read your code without proper formatting, but this demonstrates how variables are found multiple levels of nesting: def foo(): """Outer Function.""" x = 10 y = 10 def nested(): """Function nested in foo().""" y = 100 def nested_in_nested(): """Function nested in nested().""" nonlocal x nonlocal y # Search 'up' the levels for x and y. print(f'In nested_in_nested(): {x=} {y=}') # Modify x and y x += 1 y += 1 # Cannot modify y # Call nested_in_nested() from inside nested(). nested_in_nested() print(f'In nested(): {x=} {y=}') # Call nested() from inside foo(). nested() print(f'In foo(): {x=} {y=}') x = 1 # Global foo() Which prints: In nested_in_nested(): x=10 y=100 In nested(): x=11 y=101 In foo(): x=11 y=10 In the first printed line: In nested_in_nested(), the variable y is found in nested(), so y=100 is printed. It is then incremented. The variable x is not found in nested(), so Python looks next in the enclosing function foo() and finds x there. x=10 is printed. It is then incremented The nonlocal keyword allows a function to modify variables from the nearest enclosing scope that is not global. y in the outer function foo() is not modified by y = 100 in nested() because y in nested() is local to nested(). In the second printed line, notice that 'y' from the local scope of nested() has been incremented to 101, and x from the outer scope foo() has been incremented to 11. In the third printed line, the local x has been incremented The local y has not been incremented because that was not the instance of y accessed by y += 1 in nested_in_nested(). DO NOT WRITE CODE LIKE THIS. Python emphasises readability and this kind of code is horrible to read.
2 of 4
2
Nested functions are best used when you need to repeat some code that only appears in your function. Since python's functions are closures, you can access variables from the outer scope just fine, which is handy. However, as soon as you want to modify one of those variables, you should think long and hard about whether this is the right way to do things. The keywords global and nonlocal are both good indications that you're doing something wrong. They are extremely rare in production code. This is for good reason, allowing variables to be modified outside of the scope they were defined in is a terrible idea and makes debugging so much more difficult when you accidentally set them to something wrong (and this will happen). You should also avoid reusing the same variable name when the previous variable is still visible. If there's one variable called x already available, do not create a new one inside a function with the same name. This also makes debugging errors harder, and can cause problems when you think you're referring to one variable, but it turns out you're actually referring to a different object that has the same name.
🌐
W3Schools
w3schools.com › python › python_scope.asp
Python Scope
To change the value of a global ... it Yourself » · The nonlocal keyword is used to work with variables inside nested functions. The nonlocal keyword makes the variable belong to the outer function....
🌐
Python Tutorial
pythontutorial.net › home › advanced python › python nonlocal
Python nonlocal Scopes and nonlocal Variables
March 27, 2025 - And in this case, Python goes up to the global scope to find the variable: To modify variables from a nonlocal scope in a local scope, you use the nonlocal keyword. For example: def outer(): message = 'outer scope' print(message) def inner(): ...
🌐
Reddit
reddit.com › r/learnpython › what is the better way to change a variable from outside a function in a function?
r/learnpython on Reddit: What is the better way to change a variable from outside a function in a function?
February 28, 2025 -

def generic_function(x, y):

x += 1

y += 1

x = 1

y = 2

generic_function(x, y)

print(x, y)

Above the variables x and y do not change because generic_function creates local variables x and y.

But I learned I could do that this way:

def generic_function():

list\[0\] += 1

list\[1\] += 1

list = [1, 2]

generic_function()

print(list[0], list[1])

A list can be used as parameters to the function, so the generic_function will modify the list that the name list refers to. And so no unwanted local variables are created.

But it seems strange to make your program search in a list for a value so many times, is there any other way to do it? Why couldn't I change which value the name x refers to directly?

🌐
sqlpey
sqlpey.com › python › python-nested-functions-modify-outer-scope
Python Nested Functions Modify Outer Scope Variable Solutions
July 25, 2025 - This post delves into several effective ... creating or modifying a variable local to that function. This means an inner function cannot directly change a variable in the outer scope through simple assignment....
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-inner-functions
Python Inner Functions - GeeksforGeeks
May 22, 2026 - Example 2: This example shows how the nonlocal keyword allows the inner function to modify a variable from the outer function instead of creating a new local copy. ... Explanation: nonlocal tells Python to use the variable a from the outer scope ...
Top answer
1 of 3
3

First off, in this simple case you could return the desired value from inner() and assign it when calling inner(). But let's assume that this is a simplified example, and that you are in fact changing multiple variables, or returning inner somewhere else where it will be called multiple times and need to reexamine its variable.

In Python 3 you can declare variab as nonlocal, which would allow you to change it. In Python 2, the only way is to switch to mutating an object with state freshly created on each call to outer. For example, using a list:

def outer():
    variab = [""]
    #some code including, presumably, a call to inner()

    def inner():
        # some code
        variab[0] = "new_value"

    print variab[0]

Nicer variants of this can be achieved, e.g. by making variab contain a dict or a Python instance with mutable __dict__. An elegant idiom is to use the __dict__ of the inner function itself as the container:

def outer():
    def inner():
        # some code
        inner.variab = "new_value"

    inner.variab = ""
    #some code including, presumably, a call to inner()    
    print inner.variab
2 of 3
2

The cleanest way to do this is explicitly:

def outer():
    variab = ""
    #some code

    def inner(variab):
        # some code
        variab = "new_value"
        return variab

    variab = inner(variab)

    print variab

Now you don't have to worry about scoping, can test inner in isolation, etc. It is clear to the reader that inner requires access to variab to do its thing, and that variab may be different after the call.

See PEP-0020: "Explicit is better than implicit"; and "Readability counts".

🌐
Medium
martinxpn.medium.com › python-variable-scope-30-100-days-of-python-c7f74c46c0a5
Python Variable Scope (30/100 Days of Python) | by Martin Mirakyan | Medium
April 10, 2023 - The outer_function has a variable x with a value of 10 in its local scope. Within the inner_function, we use the nonlocal keyword to access and modify the variable x in the outer local scope.
🌐
GeeksforGeeks
geeksforgeeks.org › accessing-python-function-variable-outside-the-function
Accessing Python Function Variable Outside the Function - GeeksforGeeks
March 8, 2025 - Explanation: outer_fun() defines a local variable var and returns inner_fun(), which accesses var. Assigned to get_var, inner_fun() retains access to var even after outer_fun() executes, demonstrating a closure. Instead of directly accessing a variable, passing it as a function parameter allows modifications without breaking encapsulation.