foreach-ui logo
codeLanguages
account_treeDSA

Quick Actions

quizlock Random Quiz
trending_uplock Progress
  • 1
  • 2
  • 3
  • 4
  • quiz
Python
  • Understand local and global scope
  • Know how variable visibility works in functions
  • Use the global keyword appropriately
  • Avoid common scope-related bugs

Scope and Variable Lifetime

Have you ever wondered why a variable you created inside a function disappears after the function ends? Or why you can't change a variable from outside a function without special steps? Welcome to the world of scope.

Scope determines where a variable can be seen and used. Understanding scope prevents confusing bugs and helps you write cleaner, more predictable code. It's like understanding that a library card only works at your local library – context matters!


Local vs Global Scope

Think of scope like rooms in a house:


                    Scope Visualization                           

                                                                  
      
                 GLOBAL SCOPE (The House)                      
                                                               
      name = "Alice"    ← Available everywhere                 
      count = 0         ← Available everywhere                 
                                                               
            
              LOCAL SCOPE (A Room - function)                
                                                             
         def greet():                                        
             message = "Hello"  ← Only in this room          
             temp = 42          ← Only in this room          
             print(name)        ← Can see house stuff        
                                                             
            
                                                               
      # Can't see message or temp out here!                   
                                                               
      
                                                                  

Local Variables

Variables created inside a function are local – they only exist within that function:

def my_function():
    local_var = "I only exist here!"  # Local variable
    print(local_var)  #  Works

my_function()  # Prints: I only exist here!

# Outside the function:
# print(local_var)  #  NameError: name 'local_var' is not defined

Local Variables Are Isolated

def function_a():
    secret = "A's secret"
    print(f"A says: {secret}")

def function_b():
    secret = "B's secret"  # Different variable, same name!
    print(f"B says: {secret}")

function_a()  # A says: A's secret
function_b()  # B says: B's secret

# Each function has its own 'secret' - they don't interfere!

Local Variables Reset Each Call

def counter():
    count = 0  # Created fresh each call
    count += 1
    return count

print(counter())  # 1
print(counter())  # 1 (not 2! - count is recreated each time)
print(counter())  # 1

Global Variables

Variables created outside any function are global – accessible everywhere:

# Global variable - defined at the top level
greeting = "Hello"

def say_greeting():
    # Can READ global variables without any special keyword
    print(greeting)  #  Works - reading global

say_greeting()  # Hello
print(greeting)  # Hello - also works here

Reading Global Variables

PI = 3.14159  # Global constant
TAX_RATE = 0.2  # Global constant

def calculate_circle_area(radius):
    return PI * radius ** 2  # Reading PI - works fine!

def calculate_tax(amount):
    return amount * TAX_RATE  # Reading TAX_RATE - works fine!

print(calculate_circle_area(5))  # 78.53975
print(calculate_tax(100))        # 20.0

The Shadowing Problem

What happens when a local variable has the same name as a global?

name = "Alice"  # Global

def greet():
    name = "Bob"  # Local - SHADOWS the global!
    print(f"Hello, {name}")  # Uses local 'name'

greet()        # Hello, Bob
print(name)    # Alice - global unchanged!

Visual Explanation


                    Variable Shadowing                            

                                                                  
   name = "Alice"   ← GLOBAL name                                
                                                                  
   def greet():                                                  
       name = "Bob"  ← LOCAL name (shadows global)               
       print(name)   ← Uses LOCAL name = "Bob"                   
                                                                  
   greet()           → prints "Bob"                              
   print(name)       → prints "Alice" (global unchanged)         
                                                                  
   Python looks for 'name' in this order:                        
   1. Local scope (inside function) ← Found "Bob"                
   2. Global scope (if not found locally)                        
                                                                  

The global Keyword

To modify a global variable inside a function, use global:

counter = 0  # Global

def increment():
    global counter  # Tell Python: use the GLOBAL counter
    counter += 1    # Now this modifies the global!

print(counter)  # 0
increment()
print(counter)  # 1
increment()
print(counter)  # 2

Without global - Creates Local Copy

counter = 0  # Global

def broken_increment():
    # counter += 1  #  UnboundLocalError!
    # Python sees assignment, assumes local, but local doesn't exist yet
    pass

def also_broken():
    counter = counter + 1  #  Same error!
    # Python prepares a local 'counter', but tries to read it before creation

When global Is Needed


                    When to Use global                            

                                                                  
    READING global - NO global keyword needed                  
                                                                  
      total = 100                                                
      def show():                                                
          print(total)  # Just reading - OK!                     
                                                                  
    MODIFYING global - global keyword REQUIRED                 
                                                                  
      total = 100                                                
      def add(amount):                                           
          global total    # Must declare!                        
          total += amount # Now modification works               
                                                                  

⏱ Variable Lifetime

How long does a variable exist?


                    Variable Lifetime                             

                                                                  
   GLOBAL VARIABLES:                                             
   • Created when the script starts                              
   • Live until the program ends                                 
   • Always available                                            
                                                                  
   LOCAL VARIABLES:                                              
   • Created when the function is called                         
   • Destroyed when the function returns                         
   • Fresh copy each function call                               
                                                                  
   Timeline:                                                      
        
   Program starts → global vars created                          
        ↓                                                         
   Function called → local vars created                          
        ↓                                                         
   Function returns → local vars destroyed                       
        ↓                                                         
   Program ends → global vars destroyed                          
                                                                  

Demonstration

print("1. Program starts")

message = "Global message"  # Created now, lives until program ends
print(f"2. Global created: {message}")

def create_local():
    print("4. Function called - local about to be created")
    local_msg = "Local message"  # Created now
    print(f"5. Local exists: {local_msg}")
    return "done"
    # local_msg is destroyed HERE

print("3. About to call function")
create_local()
print("6. Function returned - local is destroyed")
# print(local_msg)  #  Would fail - doesn't exist anymore!
print("7. Program ends - global destroyed")

Best Practices

1. Minimize Global Variables

#  BAD: Lots of globals
total = 0
tax = 0
discount = 0

def calculate():
    global total, tax, discount
    # ... hard to track what's changing

#  GOOD: Use parameters and return values
def calculate(subtotal, tax_rate, discount_rate):
    tax = subtotal * tax_rate
    discount = subtotal * discount_rate
    total = subtotal + tax - discount
    return total, tax, discount

2. Use Constants for Unchanging Globals

#  GOOD: Global constants (uppercase convention)
PI = 3.14159
MAX_ATTEMPTS = 3
DATABASE_URL = "localhost:5432"

def calculate_circle(radius):
    return PI * radius ** 2  # Reading constant is fine!

3. Pass Data Through Parameters

#  BAD: Relies on global state
user_name = ""

def greet():
    global user_name
    print(f"Hello, {user_name}")

user_name = "Alice"
greet()

#  GOOD: Explicit parameter passing
def greet(name):
    print(f"Hello, {name}")

greet("Alice")  # Clear what data the function uses!

Practical Examples

Example 1: Game Score (Using Global Carefully)

# Sometimes global state makes sense (like a game score)
score = 0
high_score = 0

def add_points(points):
    global score, high_score
    score += points
    if score > high_score:
        high_score = score
    print(f"Score: {score} (High: {high_score})")

def reset_game():
    global score
    score = 0
    print("Game reset!")

add_points(100)   # Score: 100 (High: 100)
add_points(50)    # Score: 150 (High: 150)
reset_game()      # Game reset!
add_points(75)    # Score: 75 (High: 150)

Example 2: Configuration (Constants)

# Global configuration - read-only constants
CONFIG = {
    "debug": True,
    "max_retries": 3,
    "timeout": 30
}

def make_request(url):
    for attempt in range(CONFIG["max_retries"]):
        if CONFIG["debug"]:
            print(f"Attempt {attempt + 1} to {url}")
        # ... make request
        return "Success"
    return "Failed"

result = make_request("https://api.example.com")

Example 3: Better Alternative - Class

# For complex state, consider a class instead of globals
class GameState:
    def __init__(self):
        self.score = 0
        self.high_score = 0
        self.level = 1
    
    def add_points(self, points):
        self.score += points
        if self.score > self.high_score:
            self.high_score = self.score
    
    def reset(self):
        self.score = 0
        self.level = 1

# Use instance instead of globals
game = GameState()
game.add_points(100)
print(game.score)  # 100

Common Mistakes

1. UnboundLocalError

count = 10

def increment():
    count += 1  #  UnboundLocalError!
    # Python sees assignment, prepares local, but can't read before assignment

# Fix with global:
def increment_fixed():
    global count
    count += 1  #  Works

2. Accidentally Shadowing

data = [1, 2, 3]  # Global list

def process():
    data = [4, 5, 6]  #  Created local, didn't modify global!
    data.append(7)

process()
print(data)  # [1, 2, 3] - unchanged!

# If you wanted to modify:
def process_fixed():
    global data
    data = [4, 5, 6]  # Now modifies global

3. Mutable Default Arguments

#  DANGER: Mutable default argument!
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item("a"))  # ['a']
print(add_item("b"))  # ['a', 'b'] ← Shared list!
print(add_item("c"))  # ['a', 'b', 'c'] ← Still shared!

#  SAFE: Use None as default
def add_item_safe(item, items=None):
    if items is None:
        items = []  # New list each call
    items.append(item)
    return items

Key Takeaways


                   Remember These Points                          

                                                                  
   Local variables: Inside function, exist only during call    
                                                                  
   Global variables: Outside functions, exist throughout       
                                                                  
   Functions can READ global variables freely                  
                                                                  
   To MODIFY global, use: global variable_name                 
                                                                  
   Same name in function = local variable (shadows global)     
                                                                  
   Best practice: Use parameters and return values             
     instead of relying on globals                                
                                                                  
   Use UPPERCASE for global constants                          
                                                                  

Module Complete!

Congratulations! You've completed the Functions module!

You now understand:

  • Defining functions with def
  • Parameters and arguments for input
  • Return values for output
  • Scope for variable visibility

Functions are the building blocks of organized code. In the next module, you'll learn about Strings and Text Processing – powerful techniques for working with text data!

© 2026 forEach. All rights reserved.

Privacy Policy•Terms of Service