How to use a global variable in a function in Python?

Free Coding Questions Catalog
Boost your coding skills with our essential coding questions catalog. Take a step towards a better tech career now!

In Python, global variables are variables that are defined outside of functions and are accessible throughout the entire script or module. While they can be useful in certain scenarios, it's essential to use them judiciously to maintain code readability and prevent unintended side effects. This guide will explain how to use global variables within functions, including how to read and modify them, along with best practices and common pitfalls to avoid.

Understanding Global Variables

Global variables are declared outside of any function or class and are accessible anywhere in the module. They retain their values throughout the execution of the program unless explicitly modified.

# Global variable counter = 0 def increment(): global counter counter += 1 increment() print(counter) # Output: 1

In the above example:

  • counter is a global variable.
  • The increment function modifies the global counter using the global keyword.

Accessing Global Variables in Functions

Reading Global Variables

Functions can read global variables without any special declarations. Simply refer to the variable by its name.

# Global variable greeting = "Hello, World!" def print_greeting(): print(greeting) print_greeting() # Output: Hello, World!

Modifying Global Variables

To modify a global variable within a function, you must declare it as global using the global keyword. This informs Python that you intend to use the global version of the variable, not create a new local one.

# Global variable count = 10 def update_count(): global count count += 5 update_count() print(count) # Output: 15

Without the global keyword, Python treats count inside update_count as a local variable, leading to errors if you try to modify it before assignment.

# This will raise an UnboundLocalError count = 10 def update_count(): count += 5 # Attempting to modify without declaring as global update_count()

Error:

UnboundLocalError: local variable 'count' referenced before assignment

Using the global Keyword

The global keyword is used inside a function to declare that a variable refers to the globally scoped variable. This is necessary when you want to assign a new value to a global variable within a function.

Syntax

def function_name(): global variable_name # Now you can modify variable_name variable_name = new_value

Example

# Global variable message = "Hello" def change_message(): global message message = "Goodbye" change_message() print(message) # Output: Goodbye

In this example:

  • message is initially "Hello".
  • The change_message function declares message as global and modifies its value to "Goodbye".
  • After calling change_message, the global message reflects the new value.

Best Practices

While global variables can be convenient, overusing them can lead to code that's hard to debug and maintain. Here are some best practices to follow when working with global variables:

  1. Minimize Use of Global Variables:

    • Rely on passing parameters and returning values instead of using globals.
    • This makes functions more predictable and easier to test.
  2. Use Constants for Immutable Globals:

    • For values that should not change, use uppercase variable names to indicate that they are constants.
    PI = 3.14159
  3. Encapsulate Globals Within Classes or Modules:

    • Group related global variables within classes or separate modules to avoid cluttering the global namespace.
  4. Document Global Variables:

    • Clearly comment and document the purpose of global variables to aid future maintenance.
  5. Avoid Mutable Global Variables:

    • Mutable globals (like lists or dictionaries) can be modified from anywhere, leading to unpredictable behavior.
  6. Use Global Variables Judiciously:

    • If a variable needs to be accessed and modified by multiple functions, consider if it truly requires global scope or if there are better design alternatives.

Common Pitfalls

  1. Unintended Variable Shadowing:

    • Assigning to a variable inside a function without declaring it as global creates a new local variable, which can be confusing.
    x = 5 def func(): x = x + 1 # Error: local variable 'x' referenced before assignment func()
  2. Difficulty in Tracking Changes:

    • Since global variables can be modified from anywhere, tracking their state changes can become challenging, especially in larger codebases.
  3. Concurrency Issues:

    • In multi-threaded programs, global variables can lead to race conditions if not handled properly.
  4. Testing Challenges:

    • Functions that rely on global variables are harder to test in isolation, as they have hidden dependencies.

Alternatives to Global Variables

Instead of relying on global variables, consider the following alternatives to make your code cleaner and more maintainable:

  1. Function Parameters and Return Values:

    • Pass variables as arguments to functions and return results.
    def increment(count): return count + 1 count = 0 count = increment(count)
  2. Using Classes and Objects:

    • Encapsulate related data and behavior within classes.
    class Counter: def __init__(self): self.count = 0 def increment(self): self.count += 1 counter = Counter() counter.increment() print(counter.count) # Output: 1
  3. Modules for Shared State:

    • Use separate modules to store shared state, importing them where needed.
    # config.py settings = {} # main.py import config def set_setting(key, value): config.settings[key] = value set_setting('theme', 'dark') print(config.settings) # Output: {'theme': 'dark'}
  4. Singleton Pattern:

    • Ensure a class has only one instance and provide a global point of access to it.
    class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super(Singleton, cls).__new__(cls) return cls._instance s1 = Singleton() s2 = Singleton() print(s1 is s2) # Output: True

Practical Examples

Example 1: Reading a Global Variable

# global_example.py # Global variable WELCOME_MESSAGE = "Welcome to the Application!" def greet_user(): print(WELCOME_MESSAGE) greet_user() # Output: Welcome to the Application!

Explanation:

  • WELCOME_MESSAGE is a global variable.
  • greet_user function accesses and prints the global variable without modifying it.

Example 2: Modifying a Global Variable

# global_modify_example.py # Global variable counter = 0 def increment_counter(): global counter counter += 1 print(f"Counter is now {counter}") increment_counter() # Output: Counter is now 1 increment_counter() # Output: Counter is now 2

Explanation:

  • counter is a global variable initialized to 0.
  • increment_counter function declares counter as global and increments its value.
  • Each call to increment_counter modifies the global counter.

Example 3: Avoiding Unintended Side Effects

# unintended_side_effect.py # Global list items = [] def add_item(item): global items items.append(item) print(f"Added {item}. Current items: {items}") add_item('apple') # Output: Added apple. Current items: ['apple'] add_item('banana') # Output: Added banana. Current items: ['apple', 'banana']

Potential Pitfall:

  • The global list items is mutable and can be modified from anywhere, leading to unintended side effects.

Alternative Approach: Encapsulating in a Class

# encapsulated_example.py class ItemManager: def __init__(self): self.items = [] def add_item(self, item): self.items.append(item) print(f"Added {item}. Current items: {self.items}") manager = ItemManager() manager.add_item('apple') # Output: Added apple. Current items: ['apple'] manager.add_item('banana') # Output: Added banana. Current items: ['apple', 'banana']

Benefits:

  • Encapsulates the items list within the ItemManager class.
  • Prevents external code from modifying items directly, reducing the risk of unintended side effects.

Conclusion

Global variables in Python provide a way to store data that can be accessed and modified across different functions and modules. While they offer convenience, especially for constants or configurations, overusing them can lead to code that's hard to maintain and debug. Here's a summary of key points:

  • Reading Global Variables:
    • Accessible within functions without any special declarations.
  • Modifying Global Variables:
    • Use the global keyword inside the function to modify them.
  • Best Practices:
    • Minimize the use of global variables.
    • Use constants for immutable globals.
    • Encapsulate globals within classes or separate modules.
    • Avoid mutable global variables when possible.
  • Alternatives:
    • Pass variables as function parameters.
    • Use classes to encapsulate related data and behavior.
    • Utilize separate modules for shared state.
    • Implement design patterns like Singleton for controlled access.

By adhering to these guidelines, you can leverage global variables effectively while maintaining clean, readable, and maintainable code.


Additional Resources

TAGS
Coding Interview
System Design Interview
CONTRIBUTOR
Design Gurus Team

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
What are Datadog system design interview questions?
How to clear a meta interview?
Do JavaScript coding challenges help for interview?
Related Courses
Image
Grokking the Coding Interview: Patterns for Coding Questions
Image
Grokking Data Structures & Algorithms for Coding Interviews
Image
Grokking Advanced Coding Patterns for Interviews
Image
One-Stop Portal For Tech Interviews.
Copyright © 2024 Designgurus, Inc. All rights reserved.