Lesson 9.4: Scope – Local vs Global
What You'll Learn
- What scope means in programming
- How local variables work inside functions
- How global variables work outside functions
- How to use the
globalkeyword (and why you usually should not) - How Python looks up variable names (the LEGB rule)
- Best practices for managing scope
1. What is Scope?
Scope determines where in your program a variable can be accessed. A variable defined inside a function cannot be seen outside that function, and vice versa (with some rules).
2. Local Variables
A variable created inside a function is local to that function. It only exists while the function is running and cannot be accessed from outside:
def my_function(): message = "I am local!" # local variable print(message) my_function() # This will cause a NameError: # print(message) # 'message' does not exist out here
Function parameters are also local variables:
def double(x): result = x * 2 # both 'x' and 'result' are local return result print(double(5)) # print(x) # NameError: x is not defined # print(result) # NameError: result is not defined
Each Call Gets Its Own Local Variables
def counter(): count = 0 count += 1 print(f"count = {count}") counter() counter() counter()
Each call creates a brand-new count variable that starts at 0. The variable from the previous call is gone.
3. Global Variables
A variable created outside all functions is global. Functions can read global variables, but they cannot change them without special syntax:
greeting = "Hello" # global variable def say_hello(name): # We can READ the global variable print(f"{greeting}, {name}!") say_hello("Alice") print(greeting) # still accessible out here
Local Shadows Global
If you assign to a variable inside a function, Python creates a new local variable that shadows (hides) any global variable with the same name:
color = "blue" # global def paint(): color = "red" # NEW local variable, does NOT change global print(f"Inside: {color}") paint() print(f"Outside: {color}")
4. The global Keyword
If you truly need to modify a global variable inside a function, use the global keyword:
score = 0 def add_points(points): global score # tells Python to use the global variable score += points print(f"Score is now: {score}") add_points(10) add_points(5) print(f"Final score: {score}")
global whenever possible. It makes code harder to understand and debug because any function could change the variable. Instead, pass values as arguments and return results.
Better Alternative: Use Parameters and Return
# Instead of using global: def add_points(current_score, points): """Add points and return the new score.""" return current_score + points score = 0 score = add_points(score, 10) score = add_points(score, 5) print(f"Final score: {score}")
This approach is clearer: you can see exactly where score changes.
5. The LEGB Rule
When Python encounters a variable name, it searches for it in this order:
- Local — inside the current function
- Enclosing — inside any enclosing (outer) function
- Global — at the module (file) level
- Built-in — Python's built-in names (
print,len, etc.)
x = "global" def outer(): x = "enclosing" def inner(): x = "local" print(f"inner: {x}") inner() print(f"outer: {x}") outer() print(f"global: {x}")
6. Best Practices
Scope Best Practices
- Prefer local variables: Keep data inside functions whenever possible
- Pass data through parameters: Functions should get their input from arguments, not global variables
- Return results: Use
returnto send data back rather than modifying globals - Use
globalsparingly: Only when absolutely necessary (like configuration constants) - Use ALL_CAPS for constants: If you define a global that should not change, name it in uppercase:
MAX_SIZE = 100 - Avoid shadowing: Do not give local variables the same name as global ones or built-in functions
# BAD: Shadowing built-in 'list' # list = [1, 2, 3] # Now you can't use list() anymore! # GOOD: Use a descriptive name numbers = [1, 2, 3] # BAD: Relying on global state # total = 0 # def add(x): # global total # total += x # GOOD: Pure function def add(total, x): return total + x
Check Your Understanding
Question: What does this code print?
x = 10 def change_x(): x = 20 change_x() print(x)
Answer: 10
The function creates a local variable x set to 20. This does not affect the global x. Without the global keyword, the assignment inside the function creates a new local variable.
Try It Yourself
- Create a global variable
name = "World". Write a function that prints it without modifying it. - Write a function that tries to change the global
namewithout usingglobal. Printnameafter calling it to verify it did not change. - Rewrite the function using
globaland verify the change works. - Finally, refactor to avoid
globalentirely by using parameters and return values.
Key Takeaways
- Local variables exist only inside the function where they are created
- Global variables exist at the module level and can be read (but not modified) by functions
- Assigning to a variable inside a function creates a local variable, even if a global with the same name exists
- The
globalkeyword lets you modify global variables from within a function, but is best avoided - Python resolves names using the LEGB rule: Local, Enclosing, Global, Built-in
- Best practice: pass data in through parameters and return results