How to Create Global Variables in Python Functions

In this tutorial, we will learn how to create the global variable in the Python functions. A global variable is a type of variable that can be accessed in any part of the program including within the function. To ensure the correct functioning of your code, it is important to distinguish between accessing and modifying the values of the target global variable.

Global variable plays an essential role in software development because they ensure data sharing across an entire platform.

Using Global Variable in Python Functions

We can access and modify the global variable at any level of the program. In Python, the global variable is defined at the module level. Working with global variables can introduce some confusion when it comes to accessing and modifying them within modules and functions. While global variables can be utilized within the module itself or in other modules, their handling within functions requires careful consideration due to variations in accessing and modifying global variables.

When a functions access the global variable Python checks for variables in various scope.

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

When accessing a variable within an inner function in Python, the interpreter follows a specific search pattern. It first looks for the variable inside the function itself. If the variable is not found there, it proceeds to search within the enclosing scope of the outer function. If the variable is still not defined, Python then proceeds to search within the global and built-in scopes, in that order. If the variable is found, its value is returned. However, if the variable is not found in any of these scopes, a NameError is raised.

Let's understand the following example.

Example -

In the above example, we define the inner_function() inside the outer_function(). The inner_function() owns code block represents the local scope, while the outer_function() code block represents the non-local scope. If we call the outer_function() without declaring the some_variable, it will through a NameError exception.

If we define the some_variable as global then we get the output like Hello I am in global scope. By default, the Python interpreter searches in the local, non-local, and global scope to find the some_variable. We can define this variable in any scope and Python will find it and print its content.

This search mechanism allows to use of global variable inside the functions. But it comes with a disadvantage. For example - We can access the variable easily but can't modify the variable.

Example -

Output:

50
50

The access_number() function works fine and finds the num in the global scope. On the other hand, the modify_number() doesn't work as it is defined. Because we can't modify a variable from a higher-level scope (global) to a lower-level scope (local).

Python internally assumes that any name assigned directly within a function is considered local to that specific function. This means that if there is a variable named "num" assigned within the function, it will take precedence over the global variable with the same name. In other words, the local name "num" overshadows or hides the global variable of the same name.

In this context, global variables can be viewed as read-only names. While we can access the values of global variables, it is not possible to modify them directly.

We may encounter another exception like UnboundLocalError when we try to modify a global variable inside a function. Let's understand the following example.

Example -

When we run the above code, we first get the value of a, b, and c. Then inside function, we modify the c directly. The expected output be like this -

print(get_globals())
10 20 30
100

However, we won't get this output; instead we get the following exception.

print(get_globals())
Traceback (most recent call last):
  File "<string>", line 10, in <module>
  File "<string>", line 6, in get_globals
UnboundLocalError: cannot access local variable 'c' where it is not associated with a value

The issue arises when the assignment c = 100 creates a new local variable that takes precedence over the original global variable c. This results in a conflict between the two variables with the same name. The exception, specifically the UnboundLocalError, is triggered by the first call to print() because, at that particular moment, the local version of c is not defined yet.

This issue occurs in augmented assignment operation with global variables.

Output:

Traceback (most recent call last):
  File "", line 7, in 
  File "", line 4, in increment
UnboundLocalError: cannot access local variable 'counter' where it is not associated with a value

In Python, if a function references a variable from a global scope, the function assumes that the variable is global. If we define a variable's name in the function body it means we are define a new local variable with the same name as original global. Inside the function, we can't access the global variable directly if we define local variables with the same name in the function.

If you intend to modify a global variable within a function, it is necessary to explicitly instruct Python to use the global variable instead of creating a new local variable. Python provides the following ways to do so.

  • The global keyword
  • The built-in globals() function

The global Keyword

Earlier, we discussed how to access the global variable directly from inside a function if the local variable is not with the same name as the global. But in some scenarios, we need to change the value of the global variable. In that case, we can use the global keyword to declare that we want to refer to the global variable.

Following is the syntax of global statement.

To understand this statement, we are using the counter and increment example. We can fix the code using the global keyword.

Example -

Output:

1
1
2
2

In the updated version of the increment() function, the global keyword is used to explicitly indicate that the intention is to modify the global variable, counter. By including this statement, the function now has the ability to change the value of the counter variable within its scope.

If we use the target variable before declaration of global we will get a SyntaxError.

Output:

File "", line 5
SyntaxError: name 'counter' is assigned to before global declaration

To summarize, the global keyword is necessary when you intend to reassign or modify the value of a global variable within a function. However, if your objective is solely to read or access the value of the global variable within the function, you do not require the global keyword.

To dealing with the global variable inside the function, we can also use the built-in globals() function.

The globals() Function

The globals() function, a built-in function in Python, provides access to the name table of the global scope. This name table is a dictionary that contains the current global names along with their respective values. By utilizing this function, you can both access and modify the value of a global variable from within your functions.

The globals() function is particularly useful in situations where you have local variables that share the same name as your desired global variables, and you still need to access or modify the global variable within the function. By utilizing the globals() function, you can explicitly refer to the global variable and distinguish it from the local variable with the same name, allowing you to work with the intended global variable inside the function.

Example -

Output:

10 20 30
100
30

In the revised implementation of print_globals(), the variable "c" is referencing the local version of the variable, whereas globals()["c"] is referencing the global version.

By utilizing the globals() function, which returns a dictionary, you file can access its keys just like you would with any regular dictionary. It is important to note that to access a specific key in the globals() dictionary, you need to use the variable's name as a string.

The dictionary returned by globals() is mutable, allowing you to modify the values of existing global variables by leveraging this dictionary. In the final example, it is obvious that the global variable "c" retains its original value despite modifications made to it through the globals() dictionary.

Example -

Output:

1
2

In this particular example, the increment() function has been implemented using the globals() function instead of the global keyword. Both implementations achieve the same result, as evidenced by the consistent value of the counter variable after consecutive function calls.

However, it is important to note that using globals() to access and update global variables can make your code less readable and harder to understand, particularly in larger programs. In general, it is recommended to use the global keyword unless you specifically encounter a situation where there are local variables sharing the same name as your intended global variables.

Creating Global Variables inside a Function

As we've previously discovered, both the global keyword and the built-in globals() function can be used to access and modify global variables within a function. However, what may be particularly intriguing and surprising is that we can also employ these tools to create global variables from within a function.

Let's understand the following example.

Example -

Output:

100
100

In the given example, the function set_global_variable() utilizes the global keyword to declare "number" as a global variable. When the function is called, "number" is defined as a global variable and assigned a value of 100. Following the function call, "number" becomes accessible from any other part of the program.

Another option for defining new global variables within functions is to utilize the globals() function. This approach provides additional flexibility, enabling us to dynamically create global variables. By leveraging the globals() function, we can dynamically introduce new global variables within your functions.

Example -

Output:

100
100

Let's take a real-life example, suppose we have a configuration file in JSON format. We need to process the file and load all the configuration parameter directly into the global namespace so that these parameters can be used in the other part of code.

The config.json file may look-like as below.

In the file, the database is key which has another dictionary of keys and values. This file consists of the basic setting of the database and also defines an API key, a base URL, and a timeout for connecting to an API.

Using the following code, we can load the JSON file and create the required set of global variables.

Example -

Output:

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

The above code defines the set_config_key(), which takes the key and value as arguments. We use the globals() to create a global variable using the key as the variable name and value as its value.

The with statement is used to open the configuration; we read the file and assign the file object to the config_keys variable. The for loop process the loaded configuration and create new global variables for each key-value pair.

When to Use Global Variables

While working on a project, we encounter some situations where it is necessary to use global variables. These scenarios may involve sharing data or state across different modules, facilitating communication between various components of the system, or maintaining a centralized configuration or settings repository. Following are some cases where global variables must be used.

  • Configurations and Settings - The global variables are more appropriate if we have a setting configuration that is applied to the entire program. The global variables allow you to access the settings from anywhere in the code.
  • Small Utility Scripts - When we want to automate some part of workflow flow, we can use global variables that help to running faster.
  • Caching Data - If you need to cache data for performance reasons, then you can take advantage of global variables to store the cached data.

Apart from that global variables have some drawbacks which are given below.

  • One challenge associated with using global variables in a project is that it becomes difficult to track changes made to the variable since it can be modified from anywhere in the codebase.
  • Using global variables in the code can make testing and debugging more challenging due to the dependence of function behavior and results on the current value of the global variable.
  • Utilizing global variables in code can lead to naming conflicts, as there is a risk of inadvertently reusing the same global name in different sections of the codebase. This unintended reuse of global names can result in unexpected and erroneous outcomes. It becomes challenging to predict and control how the global variable will be accessed and modified in different parts of the code, potentially leading to unintended side effects or incorrect behavior.
  • Global variables have the tendency to break encapsulation within the code by introducing hidden dependencies among various components. By relying on global variables, different parts of your code become interconnected in an implicit manner, making it challenging to determine the exact dependencies and relationships between them.
  • Using global variables can make code refactoring a more challenging task as modifications in one part of the codebase can potentially impact other interconnected parts. Due to the implicit dependencies introduced by global variables, refactoring becomes intricate because changes to the global variable can have unintended consequences on various functions and modules throughout the code.

Conclusion

Throughout your exploration of using global variables within Python functions, you have gained valuable insights. It is obvious that accessing global variables directly within functions is feasible, but modifying them requires the use of either the global keyword or the globals() function.

Global variables serve the purpose of sharing data across multiple functions, offering convenience in certain scenarios. However, it is crucial to exercise caution and restraint when employing this type of variable. Excessive use of global variables can result in code that is complex, challenging to comprehend, debug, test, and maintain. It is advisable to use global variables judiciously, considering the potential drawbacks and aiming for code that is more readable, modular, and easy to maintain.