Using and Creating Global Variables in Your Python Functions

Using and Creating Global Variables in Your Python Functions

A global variable is a variable that you can use from any part of a program, including within functions. Using global variables inside your Python functions can be tricky. You’ll need to differentiate between accessing and changing the values of the target global variable if you want your code to work correctly.

Global variables can play a fundamental role in many software projects because they enable data sharing across an entire program. However, you should use them judiciously to avoid issues.

In this tutorial, you’ll:

  • Understand global variables and how they work in Python
  • Access global variables within your Python functions directly
  • Modify and create global variables within functions using the global keyword
  • Access, create, and modify global variables within your functions with the globals() function
  • Explore strategies to avoid using global variables in Python code

To follow along with this tutorial, you should have a solid understanding of Python programming, including fundamental concepts such as variables, data types, scope, mutability, functions, and classes.

Using Global Variables in Python Functions

Global variables are those that you can access and modify from anywhere in your code. In Python, you’ll typically define global variables at the module level. So, the containing module is their scope.

Once you’ve defined a global variable, you can use it from within the module itself or from within other modules in your code. You can also use global variables in your functions. However, those cases can get a bit confusing because of differences between accessing and modifying global variables in functions.

To understand these differences, consider that Python can look for variables in four different scopes:

  • The local, or function-level, scope, which exists inside functions
  • The enclosing, or non-local, scope, which appears in nested functions
  • The global scope, which exists at the module level
  • The built-in scope, which is a special scope for Python’s built-in names

To illustrate, say that you’re inside an inner function. In that case, Python can look for names in all four scopes.

When you access a variable in that inner function, Python first looks inside that function. If the variable doesn’t exist there, then Python continues with the enclosing scope of the outer function. If the variable isn’t defined there either, then Python moves to the global and built-in scopes in that order. If Python finds the variable, then you get the value back. Otherwise, you get a NameError:

Python
>>> # Global scope

>>> def outer_func():
...     # Non-local scope
...     def inner_func():
...         # Local scope
...         print(some_variable)
...     inner_func()
...

>>> outer_func()
Traceback (most recent call last):
    ...
NameError: name 'some_variable' is not defined

>>> some_variable = "Hello from global scope!"
>>> outer_func()
Hello from global scope!

When you launch an interactive session, it starts off at the module level of global scope. In this example, you have outer_func(), which defines inner_func() as a nested function. From the perspective of this nested function, its own code block represents the local scope, while the outer_func() code block before the call to inner_func() represents the non-local scope.

If you call outer_func() without defining some_variable in either of your current scopes, then you get a NameError exception because the name isn’t defined.

If you define some_variable in the global scope and then call outer_func(), then you get Hello! on your screen. Internally, Python has searched the local, non-local, and global scopes to find some_variable and print its content. Note that you can define this variable in any of the three scopes, and Python will find it.

This search mechanism makes it possible to use global variables from inside functions. However, while taking advantage of this feature, you can face a few issues. For example, accessing a variable works, but directly modifying a variable doesn’t work:

Python
>>> number = 42

>>> def access_number():
...     return number
...

>>> access_number()
42

>>> def modify_number():
...     number = 7
...

>>> modify_number()
>>> number
42

The access_number() function works fine. It looks for number and finds it in the global scope. In contrast, modify_number() doesn’t work as expected. Why doesn’t this function update the value of your global variable, number? The problem is the scope of the variable. You can’t directly modify a variable from a high-level scope like global in a lower-level scope like local.

Internally, Python assumes that any name directly assigned within a function is local to that function. Therefore, the local name, number, shadows its global sibling.

In this sense, global variables behave as read-only names. You can access their values, but you can’t modify them.

Getting an UnboundLocalError exception is another common issue when you try to modify a global variable inside a function. Consider the following demonstrative function that attempts to use some global variables:

Python
>>> a = 10
>>> b = 20
>>> c = 30

>>> def print_globals():
...     print(a, b, c)
...     c = 100
...     print(c)
...

Inside print_globals(), you first print the global variables a, b, and c. Then you update the value of c directly. Finally, you print the updated version of c. You may be expecting the following output:

Python
>>> # Expected output
>>> print_globals()
10 20 30
100

However, this output never appears on your screen. Instead, you get an error that might surprise you:

Python
>>> print_globals()
Traceback (most recent call last):
    ...
UnboundLocalError: cannot access local variable 'c'
    where it is not associated with a value

The problem is that the assignment c = 100 creates a new local variable that overrides the original global variable, c. So, you have a name conflict. The exception comes from the first call to print() because, at that time, the local version of c isn’t defined yet. So, you get the UnboundLocalError.

In practice, this issue most often occurs in augmented assignment operations with global variables:

Python
>>> counter = 0

>>> def increment():
...     counter += 1
...

>>> increment()
Traceback (most recent call last):
    ...
UnboundLocalError: cannot access local variable 'counter'
    where it is not associated with a value

In Python, if your function simply references a variable from the global scope, then the function assumes that the variable is global. If you assign the variable’s name anywhere within the function’s body, then you define a new local variable with the same name as your original global.

Inside a function, you can’t access a global variable directly if you’ve defined local variables with the same name anywhere in the function.

If you want to modify a global variable inside a function, then you need to explicitly tell Python to use the global variable rather than creating a new local one. To do this, you can use one of the following:

  1. The global keyword
  2. The built-in globals() function

In the following sections, you’ll learn how to use both tools in your code to change global variables from inside your functions.

The global Keyword

You’ve already learned that accessing global variables directly from inside a function is completely possible unless you have local variables with the same name in the containing function. Apart from that, what if you also need to change the variable’s value? In that case, you can use the global keyword to declare that you want to refer to the global variable.

The general syntax to write a global statement is as follows:

Python
global variable_0, variable_1, ..., variable_n

Note that the first variable is required, while the rest of the variables are optional. To illustrate how you can use this statement, get back to the counter and increment() example. You can fix the code by doing something like the following:

Python
>>> counter = 0

>>> def increment():
...     global counter
...     counter += 1
...

>>> increment()
>>> counter
1
>>> increment()
>>> counter
2

In this new version of increment(), you use the global keyword to declare that you want the function to update the global variable, counter. With this statement, you’re now able to modify the value of counter inside your function, as you can see above.

It’s important to note that you have to do your global declarations before you use the target variable. Otherwise, you’ll get a SyntaxError:

Python
>>> counter = 0

>>> def increment():
...     counter += 1
...     global counter
...
SyntaxError: name 'counter' is assigned to before global declaration

In this example, you try to increment counter without declaring it as global inside increment(). Therefore, you get a SyntaxError.

The global statement tells the Python interpreter when you find the name counter in this function, it refers to the global variable, so don’t create a local one.

In summary, you only need to use the global keyword if you want to reassign the global variable within a function. If you just need to read or access the value of the global variable from within your function, then you don’t need the global keyword.

Even though the goal of the global keyword is to deal with global variables in functions, this keyword isn’t the only tool that you can use for this purpose. You can also use the built-in globals() function.

The globals() Function

The built-in globals() function allows you to access the global scope’s name table, which is a writable dictionary containing your current global names and their corresponding values. You can use this function to either access or modify the value of a global variable from within your functions.

For example, this function comes in handy when you have local variables with the same name as your target global variables, and you still need to use the global variable inside the function:

Python
>>> a = 10
>>> b = 20
>>> c = 30

>>> def print_globals():
...     print(a, b, globals()["c"])
...     c = 100
...     print(c)
...

>>> print_globals()
10 20 30
100

>>> c
30

In this new implementation of print_globals(), c refers to the local version of the variable, while globals()["c"] refers to the global version.

Because globals() returns a dictionary, you can access its keys as you’d access the keys of a regular dictionary. Note that you need to use the variable’s name as a string to access the corresponding key in globals().

The dictionary of names that globals() returns is mutable, which means that you can change the value of existing global variables by taking advantage of this dictionary. In the final example, you can see how the global variable, c, still holds the same value.

Here’s another version of increment(). It’s a bit harder to read, but it works:

Python
>>> counter = 0

>>> def increment():
...     globals()["counter"] += 1
...

>>> increment()
>>> counter
1
>>> increment()
>>> counter
2

In this example, you’ve implemented increment() using globals() instead of the global keyword. Both implementations work the same, which you can confirm from the content of counter after consecutive calls to the function.

Note that using globals() to access and update global variables can make your code difficult to read and understand, especially for large programs. It’s generally better to use the global keyword unless you have local variables with the same name as your target globals.

Understanding How Mutability Affects Global Variables

Python has mutable and immutable data types. Mutable types, such as lists and dictionaries, allow you to change or mutate their values in place. In contrast, immutable types, like numbers, strings, and tuples, don’t allow you to modify their values in place.

To quickly illustrate how mutability and immutability work in Python, consider the following example, where you mutate a list in place, changing the value of its elements or items:

Python
>>> numbers = [1, 2, 3]
>>> id(numbers)
4390329600
>>> numbers[0] = 10
>>> numbers[1] = 20
>>> numbers[2] = 30
>>> numbers
[10, 20, 30]
>>> id(numbers)
4390329600

In this example, you mutate the value of numbers. Because Python lists are mutable objects, this mutation doesn’t change the identity of your list object, only its value. You can confirm this by comparing the output of the built-in id() function before and after the mutations.

Now, what will happen if you try to perform a similar action on an immutable type like a tuple? In this code example, you give it a go:

Python
>>> letters = ("a", "b", "c", "d")
>>> letters[0] = "aa"
Traceback (most recent call last):
    ...
TypeError: 'tuple' object does not support item assignment

Here, you use a tuple to store letters. Python tuples are immutable, so you can’t change their items in place like you did with your list of numbers. If you try to do it, then you get a TypeError.

When it comes to using global variables that point to mutable objects inside your functions, you’ll note that it’s possible to change their values in place directly.

For example, say that you’re creating a REST API application. For convenience, you use a global dictionary to share the API configurations across the app’s code. Also for convenience, you write a short function that allows you to update the configuration parameters:

Python
>>> config = {
...     "base_url": "https://example.com/api",
...     "timeout": 3,
... }

>>> def update_config(**kwargs):
...     for key, value in kwargs.items():
...         if key in {"api_key", "base_url", "timeout"}:
...             config[key] = value
...         else:
...             raise KeyError(key)
...

>>> update_config(api_key="111222333")
>>> config
{
    'api_key': '111222333',
    'base_url': 'https://example.com/api',
    'timeout': 3
}

>>> update_config(timeout=5)
>>> config
{
    'api_key': '111222333',
    'base_url': 'https://example.com/api',
    'timeout': 5
}

In this example, the update_config() function allows you to update the app’s configuration parameters. The function takes keyword-only arguments. Each argument must be a valid configuration parameter with its corresponding value. You check this condition with the in operator in a conditional statement. If the parameter is invalid, then the function raises a KeyError.

Because Python dictionaries are mutable data types, you can change the values of config in place from within update_config() without using global or globals(). You can even add new key-value pairs if they’re valid configuration parameters. For example, the first call to update_config() adds the api_key parameter, while the second call updates the timeout parameter.

It’s important to note that configurations and settings are often an important part of an app or system’s global state. Changing a configuration while that system is running mutates its global state. You should only make this type of change if you’re being very careful. Some apps and software systems ask for a restart or reload after you change some of their configuration parameters. That’s a good way to deal with this kind of state mutation.

Creating Global Variables Inside a Function

As you’ve already learned, you can use the global keyword or the built-in globals() function to access and modify a global variable inside a function. What’s really interesting and probably surprising is that you can also use these tools to create global variables inside a function.

In this example, you create a global variable inside a function using the global keyword:

Python
>>> def set_global_variable():
...     global number
...     number = 7
...

>>> set_global_variable()
>>> number
7

Here, the set_global_variable() function uses the global keyword to define number as a global variable. When you call the function, number is defined, and its value is set to 7. After the call, you can access number from anywhere else in the program.

You can also use the globals() function to define new global variables inside your functions. This tool gives you additional flexibility, allowing you to create global variables dynamically:

Python
>>> def dynamic_global_variable(name, value):
...     globals()[name] = value
...

>>> dynamic_global_variable("number", 42)
>>> number
42

In this example, the dynamic_global_variable() function uses the globals() function to define a new global variable using a name as a string and a value. The call to your function creates a new global variable called number with a value of 42.

For a more realistic example, say that you have a configuration file in JSON format. You want to process the file and load all the configuration parameters directly into your global namespace so that you can use these parameters in other parts of your code as global variables.

Your config.json file may look something like this:

JSON
{
    "database": {
      "host": "localhost",
      "port": 5432,
      "name": "database.db",
      "user": "username",
      "password": "secret"
    },
    "api_key": "111222333",
    "base_url": "https://example.com/api",
    "timeout": 60
}

This file defines a "database" key, whose value is a dictionary of keys and values. You’ll use this dictionary as the initial setting for your application’s database. The file also defines an API key, a base URL, and a timeout for connecting to an API.

The following code takes care of loading the JSON file and creating the required set of global variables for you:

Python
>>> import json

>>> def set_config_key(key, value):
...     globals()[key] = value
...

>>> with open("config.json") as json_config:
...     for key, value in json.load(json_config).items():
...         set_config_key(key, value)
...

>>> database
{
    'host': 'localhost',
    'port': 5432,
    'name': 'database.db',
    'user': 'username',
    'password': 'secret'
}
>>> api_key
'000111222333'
>>> base_url
'https://example.com/api'
>>> timeout
60

In this code snippet, you define set_config_key(), which takes key and value as arguments. Then you use globals() to create a global variable using key as the variable name and value as its value.

In the with statement, you open the configuration file for reading and assign the file object to the json_config variable. Then you use a for loop to process the loaded configuration and create new global variables for each key-value pair.

After you’ve completed this process, you can access all your configuration parameters as global variables in your code.

Even though defining global variables within your functions using either the global keyword or the globals() function is perfectly possible in Python, it’s not a best practice. You must be careful when defining global variables in this way. Those variables become available to your entire program, so other pieces of your code can modify them. Because of this, you can end up with code that’s difficult to understand, test, maintain, and debug.

Maybe you’re noticing a bit of a pattern. There are plenty of ways to use and define global variables in your functions, but does that mean you should? In the next section, you’ll explore this question.

Deciding When to Use Global Variables

In your programming journey, you’ll find some situations where using a global variable may be appropriate or even necessary. For example, you may use global variables to handle:

  • Configurations and settings: If you have settings that apply to your entire program, then using global variables can be a quick solution that will allow you to access these settings from anywhere in your code.
  • Small utility scripts: If you’re writing small scripts to automate parts of your workflow or complete tiny tasks, then using global variables can help you get up and running faster, stopping you from overengineering your solutions.
  • Caching data: If you need to cache data for performance reasons, then you can take advantage of global variables to store the cached data.

It’s important to note that you should use global variables sparingly and only when absolutely necessary. If you decide to use global variables in your code, then make sure to document their use, especially noting why you’re relying on them.

In practice, using global variables in your code may have some drawbacks. For example, global variables can:

  • Make it difficult to keep track of changes to the variable because you can change the variable from anywhere in your code
  • Generate unwanted side effects because changes to a global variable can impact the behavior of other parts of your code
  • Make your code difficult to test and debug because the behavior and result of your functions will depend on the global variable’s current value
  • Affect your code’s reusability because functions that rely on global variables are tightly coupled to those variables
  • Cause naming conflicts because you might accidentally reuse a global name in different parts of your code, causing unexpected results
  • Break encapsulation because global variables introduce hidden dependencies between different parts of your code
  • Make your code hard to refactor because changes in one part of the code can affect other parts

While you can take advantage of global variables to solve specific problems, you’ll be better off minimizing their use in your code. If you still need to use them, then you can avoid some of their downsides by making them constants. That’s because most of the problems with using global variables come from changing their value during your code’s execution.

In the following sections, you’ll learn about some commonly used strategies and techniques to avoid using global variables in your functions.

Avoiding Global Variables in Your Code and Functions

As you learned in the previous section, relying on global variables in your functions and in your code can cause a few undesirable effects. These variables can make your code harder to understand, test, and debug. They can also lead to less maintainable and reusable code. So, you must use global variables with care and control.

Fortunately, there are some neat strategies that you can use to minimize the need for global variables in your code.

Use Global Constants

Perhaps the most intuitive strategy for avoiding global variables is to use global constants. Unlike variables, constants must not change their value during the code execution. So, they promote the safe use of global names.

To illustrate how to use constants instead of using global variables, say that you have some general configuration parameters and want to make them accessible from all parts of your program. In this case, you can use global constants. You’ll typically define constants at the top of your module right after the imports.

Here’s an example of some constants in Python:

Python
API_KEY = "111222333"
BASE_URL = "https://example.com/api"
TIMEOUT = 3

You can use constants to store values that won’t change during your program’s execution. Constants can help you prevent accidental modification of values. They also improve code readability and maintainability.

Once you’ve defined your constants, you can access them in your functions across your code. You just need to make sure to keep them unchanged. For example, below is a function that loads an image from NASA’s main API page:

Python
# nasa.py

import webbrowser

import requests

API_KEY = "DEMO_KEY"
BASE_URL = "https://api.nasa.gov/planetary"
TIMEOUT = 3

def load_earth_image(date):
    endpoint = f"{BASE_URL}/apod"
    try:
        response = requests.get(
            endpoint,
            params={
                "api_key": API_KEY,
                "date": date,
            },
            timeout=TIMEOUT,
        )
    except requests.exceptions.RequestException as e:
        print(f"Error connecting to API: {e}")
        return

    try:
        url = response.json()["url"]
    except KeyError:
        print(f"No image available on {date}")
        return

    webbrowser.open(url)

In this example, you import webbrowser from the Python standard library. This module allows you to quickly open URLs in your default browser. Then you import the requests library to make HTTP requests to the target REST API.

Inside load_earth_image(), you access the three global constants directly, just like you would do with any global variable in Python. However, you don’t change the value of any of the constants inside the function.

Now you can reuse these constants in other related functions as well. Using constants this way allows you to improve your code’s readability and maintainability. Additionally, because they’re constant, you don’t have to keep track of their current values when you’re debugging or testing the code. You’ll always know their values.

To give the above example a try, go ahead and run the following code:

Python
>>> from nasa import load_earth_image

>>> load_earth_image("2023-04-21")

The call to load_earth_image() will get you the image that NASA has for April 21, 2023. The image will open in your default browser. You can experiment with other dates and get your own images.

Take Arguments and Return Values in Functions

Writing functions that take arguments and return values instead of relying on global variables is another good strategy to avoid global variables in your code. These types of functions are known as pure functions and are the foundation of functional programming, which is a popular programming paradigm nowadays.

Pure functions are often totally decoupled from other parts of your code. More importantly, they don’t produce any side effects, like changing the state of global variables. These features make them more reusable and easier to understand, debug, test, and maintain.

As an example, here’s a new implementation of your old friend increment() without using a global variable inside the function. In this case, the function just takes a value as an argument and returns it incremented by one:

Python
>>> def increment(value=0):
...     return value + 1
...

>>> counter = increment()
>>> counter
1
>>> counter = increment(counter)
>>> counter
2
>>> counter = increment(counter)
>>> counter
3

This new version of increment() doesn’t rely on external values from global variables. So, its result will only depend on its input argument. Every time you run this function with the same argument, you’ll get the same result, which makes this function easier to test, understand, and debug.

The function is completely decoupled from any other part of your program so that you can reuse it even in a different program.

In this example, you mutate your counter variable only in the global scope. You don’t perform inter-scope mutations, so you make your code safer and easier to understand.

Use Classes, Methods, and Attributes

Sometimes you have one or more functions that operate on or with some global variables. In those cases, you can think of writing a class that turns the functions into methods and the global variables into instance attributes.

For example, say that you’re coding an app to manage your bank account. You start by creating a bunch of functions that operate on the account’s balance:

Python
# account_global.py

balance = 0

def deposit(amount):
    global balance
    balance += amount
    print(f"Successful deposit: +${amount:,.2f}")

def withdraw(amount):
    global balance
    if balance - amount > 0:
        balance -= amount
        print(f"Successful withdrawal: -${amount:,.2f}")
    else:
        print("Not enough funds for this transaction")

def get_balance():
    return balance

def main():
    while True:
        operation = input(
            "What would you like to do?\n"
            " d) deposit  "
            " w) withdraw  "
            " b) balance  "
            " q) quit\n"
            "> "
        )
        if operation in "dD":
            amount = float(input("Enter the deposit amount: "))
            deposit(amount)
        elif operation in "wW":
            amount = float(input("Enter the withdrawal amount: "))
            withdraw(amount)
        elif operation in "bB":
            print(f"Current balance: ${get_balance():,.2f}")
        elif operation in "qQ":
            print("Goodbye!")
            break
        else:
            print("Invalid operation. Please try again.")

main()

In this code, you rely on a global variable to store the balance of your bank account. You have three functions that provide common operations on the account balance. You can deposit money, withdraw money, and check the current balance of your account.

The main() function defines a while loop that presents you with a text-based user interface (TUI). Through this interface, you can tell the app to perform the desired operations on your account.

Here’s how this app works in practice:

Shell
$ python account_global.py
What would you like to do?
 d) deposit   w) withdraw   b) balance   q) quit
> d
Enter the deposit amount: 6000
Successful deposit: +$6,000.00
What would you like to do?
 d) deposit   w) withdraw   b) balance   q) quit
> w
Enter the withdrawal amount: 2380
Successful withdrawal: -$2,380.00
What would you like to do?
 d) deposit   w) withdraw   b) balance   q) quit
> b
Current balance: $3,620.00
What would you like to do?
 d) deposit   w) withdraw   b) balance   q) quit
> q
Goodbye!

Great! The app works as expected. It allows you to make deposits, withdraw funds, and check your current balance. Now say that you don’t like depending on global variables too much, and you decide to refactor the app using a class. To do this, you need to run the following steps:

  1. Define a class with an appropriate name. Account works for this example.
  2. Move the global variables into the class, converting them into instance attributes.
  3. Move the functions into the class as instance methods.

Here’s the refactored code:

Python
# account_class.py

class Account:
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        print(f"Successful deposit: +${amount:,.2f}")

    def withdraw(self, amount):
        if self.balance - amount > 0:
            self.balance -= amount
            print(f"Successful withdrawal: -${amount:,.2f}")
        else:
            print("Not enough funds for this transaction")

def main():
    account = Account()
    while True:
        operation = input(
            "What would you like to do?\n"
            " d) deposit  "
            " w) withdraw  "
            " b) balance  "
            " q) quit\n"
            "> "
        )
        if operation in "dD":
            amount = float(input("Enter the deposit amount: "))
            account.deposit(amount)
        elif operation in "wW":
            amount = float(input("Enter the withdrawal amount: "))
            account.withdraw(amount)
        elif operation in "bB":
            print(f"Current balance: ${account.balance:,.2f}")
        elif operation in "qQ":
            print("Goodbye!")
            break
        else:
            print("Invalid operation. Please try again.")

main()

In this new version of your accounting program, you’ve defined a class called Account. This class has an instance attribute to store the account’s balance. This attribute used to be your old balance global variable.

You also converted the deposit() and withdraw() functions into instance methods with the current instance, self, as the first argument. Finally, inside the loop, you instantiate the Account class and call its methods on that instance to make the app work the same as the old version.

Note that in this implementation, you don’t have a .get_balance() method. So, to access the account balance, you can directly use the .balance attribute.

Conclusion

You’ve learned a lot about using global variables, especially inside your Python functions. You’ve learned that you can access global variables directly in your functions. However, to modify a global variable in a function, you must use either the global keyword or the globals() function.

Global variables allow you to share data across multiple functions, which can be useful in some situations. However, you should use this type of variable carefully and sparingly to avoid writing code that’s difficult to understand, debug, test, and maintain.

In this tutorial, you’ve learned how to:

  • Work with global variables in Python
  • Directly access global variables within your Python functions
  • Modify and create global variables within functions using the global keyword
  • Access, create, and modify global variables within your functions with the globals() function
  • Use strategies to avoid using global variables in Python code

Now you know what it takes to correctly use global variables inside functions in Python, so you can use them effectively where appropriate. You also know that avoiding global variables is the best way to go most of the time. This will allow you to write more modular, maintainable, and reusable code.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Leodanis Pozo Ramos

Leodanis Pozo Ramos Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He's a self-taught Python developer with 6+ years of experience. He's an avid technical writer with a growing number of articles published on Real Python and other sites.

» More about Leodanis

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.


Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Tutorial Categories: best-practices intermediate python