Concepts / Variable Shadowing and Name Conflicts

Variable Shadowing and Name Conflicts

Local variables belong only to the function in which they are declared and are independent of global variables with the same name.

  • Programming
Interactive lab

Try it: Scope: Local, Enclosing, Global, Built-in

How Python looks up a name Local → Enclosing → Global → Built-in, why assigning to a name inside a function makes it local (and raises UnboundLocalError if it is read first), and what global, nonlocal and closures change.

How it works

  1. Before a function runs, Python marks every name assigned inside it as local to that function, unless it is declared global or nonlocal.
  2. Reading a name searches the local namespace, then enclosing functions, then the module's globals, then the built-ins; the first hit wins.
  3. A local name read before it has a value raises UnboundLocalError (Python does not fall back to the global).
  4. global x makes assignments go to the module namespace; nonlocal x makes them go to the nearest enclosing function.
  5. A function's local frame disappears when it returns, unless an inner function (a closure) still uses its variables.

Default run (10 steps): Ready: Local shadows global. Every name is looked up Local, then Enclosing, then Global, then Built-in. … Finished. Printed: inside: 99 / outside: 10.

Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Built-ins shows only the names the script used.

Educational simulation

Loading the simulation…

One Name, Two Variables

A name can appear both outside and inside a function without referring to one shared variable. The variable outside the function is global, while the variable declared inside the function is local to that function. These variables are independent, even when their names are identical.

What do you think happens?

A global variable named count has the value 0. A function is called with a parameter also named count, and the function changes its local count to 1. After the function returns, what value does the global count have?

  • 0

  • 1

  • The global count no longer exists

Reveal answer
Answer:

0

The parameter count is a local variable. It receives a value from the caller, but modifying that local variable does not change the caller's variable.

countglobal variable: 0incrementfunction boundarycountlocal variable: 1usesoutside function
When a function refers to a name that exists both inside and outside the function, which variable does the function use?

Following a Name Through a Call

The safest way to understand a name conflict is to trace execution in order. First identify the variable outside the function. Then, when the function is called, identify the local variable created inside it. While the function is running, the name inside the function refers to the most local scope available. The name outside the function continues to refer to the global variable.

Worked example

Tracing an Independent Parameter

A global variable named score has the value 5. A function receives a parameter named score and changes its local value to 10. Determine the values while the function runs and after it returns.

  1. 1
    Before the call

    The name score outside the function refers to the global variable, whose value is 5.

  2. 2
    At the call

    The function parameter score is created as a local variable and receives the argument value.

  3. 3
    Inside the function

    The name score refers to the local parameter because that is the most local scope available. Changing it changes the local variable.

  4. 4
    After the return

    The local score is destroyed when the function returns. The global score remains 5 because changing the local parameter did not change the caller's variable.

Result

The local and global variables had the same identifier but remained independent. The global score stayed 5.

Programglobal scopeFunction Afunction boundaryvaluelocal to Function AFunction Bseparate function boundarycontainsdefinescontains
Which parts of the program can access a variable declared inside a particular function or block?

Scope and Lifetime

Scope describes which parts of a program can access a variable. A function creates a boundary: variables declared inside it are accessible only within that function. Variables declared outside all functions are global and can be accessed from anywhere in the program. The block where a variable is defined determines its scope, and a name refers to the most local scope available.

Lifetime describes how long a local variable exists. A local variable is created when its function is called and destroyed when the function returns. A global variable exists for the entire duration of the program. Therefore, a local name cannot be used after its function has ended.

Call 1local valuevaluecreated for Call 1Returnlocal value destroyedCall 2new local valuevaluecreated for Call 2createsends atcreates
What happens to a function's local variable when the function is called with an argument or called again later?

Parameters and Caller Values

A function parameter is a local variable with a value supplied by the caller. The parameter receives the argument when the function is called, but it remains local to the function. If the function modifies the parameter, that modification affects the local variable, not the caller's variable.

Execution pointName being examinedVariable referred toValue or status
Before the function callscoreGlobal score5
Inside the functionscoreLocal parameter score10 after local modification
After the function returnsscoreGlobal score5
After the function returnsLocal parameter scoreNo longer existsAccess would cause a NameError

A generated trace showing that a parameter and a same-named global variable are independent.

countglobal: 0countlocal: 1countglobal: 0countlocal variable destroyedremainsends when function returns
At each point in execution, which variable does a name refer to, and how does that affect the resulting value?

Reading a Scope Error

When a scope-related error appears, do not decide what a name means from its spelling alone. Locate the block where the variable was defined, determine whether execution is still inside that function, and then check whether a more local variable shadows a global variable with the same name.

  • Common mistake

    Assuming that changing a parameter changes the caller's variable.

    What it looks like

    A function receives a parameter named count and changes its local count.

    Why it fails

    A parameter is a local variable. Its value comes from the caller, but the parameter remains independent inside the function.

    Do this instead

    Trace the caller's variable and the parameter as two separate variables.

  • Common mistake

    Assuming that a same-named local variable replaces the global variable.

    What it looks like

    Both the global scope and a function contain a variable named value.

    Why it fails

    The variables belong to different scopes. Inside the function, the local name is used; outside the function, the global name is used.

    Do this instead

    Identify the most local scope available at each use of the name.

  • Common mistake

    Trying to use a local variable after its function returns.

    What it looks like

    A variable named greeting is created inside a function and referenced after the function call ends.

    Why it fails

    The local variable is destroyed when the function returns, so it no longer exists.

    Do this instead

    Use a value that exists in the current scope, such as a name assigned in the global scope, or arrange for the function's result to be used while it is available.

  • Common mistake

    Debugging only the final value instead of tracing execution.

    What it looks like

    A name appears to have an unexpected value after a function call.

    Why it fails

    The same spelling may refer to different variables at different points in execution.

    Do this instead

    Record the scope and value of the name before the call, inside the function, and after the return.

messageglobal variable existsgreetinglocal to functionmessageglobal variable remainsgreetingNameError after returnremains availableno longer exists
How does identifying the active scope explain the value before a function call and the error after it returns?

Safer Function Design

Best practice

Keep variables local to the functions that use them whenever possible. Local scope isolates a variable from code in other functions, so another function cannot accidentally modify that local variable. This isolation reduces the amount of code you must inspect when debugging an unexpected value.

FeatureLocal variableGlobal variable
Where it is definedInside a functionOutside all functions
Where it can be accessedWithin its functionAnywhere in the program
When it is createdWhen the function is calledFor the duration of the program
When it endsWhen the function returnsAt the end of the program
Effect of a same-named variableThe local name is used inside the functionThe global name is used outside the function

Comparing the scope and lifetime of local and global variables.

Scope Tracing Practice

MEDIUM

A program has a global variable named total with the value 0. A function receives a parameter named total, changes that parameter to 4, and then returns. Trace the name total at three points: before the call, inside the function, and after the function returns. For each point, identify whether the name refers to the global variable or the local parameter.

Hints
  • A function parameter is a local variable.
  • The most local available scope determines which variable the name refers to.
  • A local variable is destroyed when its function returns.
EASY

A function creates a local variable named greeting. After the function returns, another statement tries to use greeting. Explain why this produces a NameError, and identify whether a separately assigned global variable named message would still exist.

Hints
  • Check where each name was defined.
  • Compare the lifetime of a local variable with the lifetime of a global variable.
  • A local variable cannot be accessed after its function ends.

Key Takeaways

  1. 1
    A local variable belongs only to the function in which it is declared.
  2. 2
    A local variable and a global variable can share a name while remaining independent.
  3. 3
    The most local scope available determines which variable a name refers to.
  4. 4
    Function parameters are local variables, so modifying them does not change the caller's variables.
  5. 5
    Local variables are created when a function is called and destroyed when it returns; using one afterward causes a NameError.

At a glance

  • Variable shadowing occurs when a local and global variable use the same name; the local variable is used inside its function.
  • Scope is determined by the block where a name is defined.
  • Function calls create local variables, and returning destroys them.
  • A parameter receives a caller's value but remains an independent local variable.
  • To debug a name conflict, trace the name's scope, value, and lifetime at each point in execution.

Related concepts

More concepts starting with V