Python
global variables
functions
duplicates
programming

Python function global variables?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Global variables in Python are easy to read but easy to misuse. The most important rule is that a function can read a global name without special syntax, but if the function assigns to that name, Python treats it as local unless you explicitly declare it as global.

Reading a global variable

If a variable is defined at module level, a function can read it directly.

python
1message = "hello"
2
3def show_message():
4    print(message)
5
6show_message()

This works because the function is only reading message, not assigning to it.

Python resolves names using local scope first, then enclosing scopes, then global scope, then built-ins. For simple reads, that usually feels natural.

Why assignment changes the rules

As soon as you assign to a name inside a function, Python treats that name as local to the function body unless told otherwise.

python
1counter = 0
2
3def increment():
4    counter = counter + 1
5    return counter
6
7increment()

This raises UnboundLocalError. Python sees counter on the left side of an assignment, decides it is a local variable, and then discovers you are trying to read that local variable before it has a value.

Using the global keyword

If you really do want to modify the module-level variable, declare it with global.

python
1counter = 0
2
3def increment():
4    global counter
5    counter += 1
6    return counter
7
8print(increment())
9print(increment())

This tells Python that assignments inside the function should target the module-level counter rather than creating a new local variable.

That said, global is a language feature to use sparingly. It makes functions depend on hidden external state, which is harder to test and reason about.

A better pattern: pass values in and return values out

Most of the time, explicit data flow is clearer than modifying globals.

python
1def increment(value):
2    return value + 1
3
4counter = 0
5counter = increment(counter)
6counter = increment(counter)
7
8print(counter)

This version is more reusable and easier to unit test because the function has no hidden dependency on module state.

Mutable globals behave differently

Another source of confusion is that you can modify the contents of a global mutable object without using global, as long as you are not rebinding the variable itself.

python
1items = []
2
3def add_item(value):
4    items.append(value)
5
6add_item("apple")
7add_item("banana")
8print(items)

This works because items.append mutates the existing list object. You are not assigning a new list to the name items.

But this would need global:

python
1items = []
2
3def reset_items():
4    global items
5    items = []

That difference between mutating an object and rebinding a name is one of the most common stumbling blocks in Python scope rules.

When globals are acceptable

Globals are reasonable for values such as module-level constants and simple configuration:

python
API_BASE_URL = "https://api.example.com"
DEFAULT_TIMEOUT = 10

These are read-only by convention and do not create the same problems as writable global state.

For shared mutable state, prefer a class, a function parameter, a context object, or dependency injection. Those patterns make ownership and lifecycle much clearer.

Common Pitfalls

  • Reading a global is fine, then assuming assignment will work the same way without global.
  • Confusing mutation of a list or dictionary with rebinding the variable name.
  • Using globals for state that should be passed as function arguments.
  • Hiding dependencies inside global state and making testing harder.
  • Overusing global instead of structuring code around explicit inputs and outputs.

Summary

  • Functions can read module-level variables without special syntax.
  • If a function assigns to a global name, you need the global keyword.
  • 'global changes name binding, not object mutability rules.'
  • Mutating a global list or dictionary is different from rebinding the variable.
  • In most cases, passing values into functions is cleaner than relying on writable globals.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.