To access variables outside a function in Python, return the value from the function and store the result in a variable where you called it. A local variable disappears when the function ends, but the value you return doesn’t:
def get_total():
total = 84.50
return total
total = get_total() # 84.5, usable here
I tested each snippet on Python 3.12.5 in the Command Prompt, so the outputs below are real.
In this tutorial, we’ll cover return values, function attributes, closures, classes, modules and the global keyword.
Why can’t you use a local variable outside its function?
A name assigned inside a function is local. Python creates it when the call starts and throws it away when the call returns, so code after the call can’t see it:
def checkout():
order_total = 84.50 # local: lives only while checkout() runs
print(f"Inside: ${order_total:.2f}")
checkout()
print(f"Outside: ${order_total:.2f}")
Output:
Inside: $84.50
Traceback (most recent call last):
File "C:\pyguides\checkout_scope.py", line 6, in <module>
print(f"Outside: ${order_total:.2f}")
^^^^^^^^^^^
NameError: name 'order_total' is not defined

order_total no longer exists.The full lookup order (local, enclosing, global, built-in) is in my guide to Python variable scope.
Return the value from a Python function (the best way)
Returning is the cleanest fix, and you can return several values as a tuple and unpack them in one line:
def checkout(prices, tax_rate):
subtotal = sum(prices)
tax = round(subtotal * tax_rate, 2)
total = subtotal + tax
return subtotal, tax, total # hand the values back
subtotal, tax, total = checkout([19.99, 45.00, 12.51], 0.0825)
print(f"Subtotal: ${subtotal:.2f}")
print(f"Tax: ${tax:.2f}")
print(f"Total: ${total:.2f}")
Output:
Subtotal: $77.50
Tax: $6.39
Total: $83.89

checkout() come back to the caller and print as dollar amounts.For dictionaries, named tuples and other ways to send back more than one value, see returning multiple values from a function in Python.
Store values as attributes on the function object
Functions are objects, so you can hang attributes on them and read them from outside:
def ship_order(state):
ship_order.count += 1
ship_order.last_state = state # store it ON the function object
ship_order.count = 0 # set before the first call
ship_order("TX")
ship_order("CA")
ship_order("NY")
print("orders shipped:", ship_order.count)
print("last state:", ship_order.last_state)
Output:
orders shipped: 3
last state: NY
Set the attribute before the first call, or += 1 raises AttributeError. I use this for small counters, not core data.
Keeping a value alive across calls is the main idea behind static variables in Python functions.
How does a closure keep an inner function’s variable alive?
A closure is an inner function that remembers variables from the function that created it. The outer call has finished, yet the inner function still uses its rate:
def make_tip_calculator(rate):
def tip(bill):
return round(bill * rate, 2) # 'rate' comes from the enclosing call
return tip
tip_18 = make_tip_calculator(0.18)
tip_20 = make_tip_calculator(0.20)
print(f"18% tip on $62.40: ${tip_18(62.40):.2f}")
print(f"20% tip on $62.40: ${tip_20(62.40):.2f}")
# peek at the captured variable from outside
print(tip_18.__code__.co_freevars, tip_18.__closure__[0].cell_contents)
Output:
18% tip on $62.40: $11.23
20% tip on $62.40: $12.48
('rate',) 0.18

__closure__ shows the captured value from outside.The last line shows the value is stored on the function. Peek at cell_contents when you debug, but just call the function in real code.
New to inner functions? See calling a function within a function in Python.
Keep state on a class instance and read it from outside
When several values belong together, use a class. Methods write to self, and you read those attributes with a dot:
class Register:
def __init__(self, store):
self.store = store
self.sales = [] # instance state, reachable from outside
def ring_up(self, amount):
self.sales.append(amount)
self.total = round(sum(self.sales), 2)
reg = Register("Austin #12")
reg.ring_up(24.99)
reg.ring_up(8.75)
print(reg.store, "sales:", reg.sales)
print(f"total: ${reg.total:.2f}")
Output:
Austin #12 sales: [24.99, 8.75]
total: $33.74

ring_up() are read from outside through reg.The __init__ method sets the starting state; Python class constructors with parameters explains it step by step.
Access a function’s variables from another file through module attributes
Top-level names in a module are attributes of that module, so other files can read what a function stored there:
# inventory.py
stock = {}
def receive(item, qty):
stock[item] = stock.get(item, 0) + qty
receive.last_item = item
import inventory
inventory.receive("coffee beans", 40)
inventory.receive("oat milk", 24)
print("stock:", inventory.stock) # module attribute
print("last item:", inventory.receive.last_item)
Output:
stock: {'coffee beans': 40, 'oat milk': 24}
last item: oat milk
You’ll notice receive() didn’t need global: it changes the dict’s contents and sets an attribute, and neither rebinds a name.
For the import side, see calling a function from another file in Python.
When to use the Python global keyword instead
If your function must assign a new value to a module-level name, write global name first, or Python treats it as local.
Rebinding, nonlocal and a shared config module are covered in setting global variables in Python functions, and the error you get without it is explained in UnboundLocalError: local variable referenced before assignment.
Which way to get a variable out of a Python function?
| Approach | Use it when | Read it with |
|---|---|---|
return | You need the result once (default choice) | x = func() |
| Function attribute | Small counter or debug value | func.count |
| Closure | A configured helper function | helper(arg) |
| Class instance | Several related values change over time | obj.total |
| Module attribute | Data shared between files | module.stock |
global | Rebinding a module-level name | name |
A few more posts on functions worth opening next:
- The Python return statement
- Return a tuple in Python
- Python variables explained
- Python classmethod() function
Frequently asked questions
How do I use a variable from a function outside of it in Python?
Return it with return and assign the call to a variable, like total = get_total().
Why do I get NameError when I print a function’s variable?
It’s local, so it only exists while the function runs, so the name isn’t defined after the call.
How do I use a variable from one function in another function?
Return it from the first function and pass it as an argument to the second, or keep both functions as methods on one class.
Can I access a local variable without returning it?
You can’t once the call ends. Store it on the function, an object or a module instead, or return it.
Is using global variables bad practice in Python?
Not always, but they hide state and make testing harder. Prefer return values or a class, and keep global for small scripts.
Where are Python scopes documented?
See Python scopes and namespaces in the official tutorial.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn