Guide Python Intermediate

6.10 Variables in Functions

How Python passes arguments into functions, why mutable and immutable arguments behave differently when modified inside a function, and the return-value pattern that follows from it.

2 min read

Passing Variables

What Is It?

Python passes arguments by “assignment” — the parameter name inside the function becomes a new reference to the same object the caller passed in. It’s neither a copy of the data (unlike C’s pass-by-value) nor a true reference-to-the-variable (unlike C++’s pass-by-reference); this model is sometimes called “pass by object reference.”

Why Does It Matter?

Whether changes inside the function are visible to the caller depends entirely on whether the argument’s type is mutable, not on any special syntax — building directly on 6.4 Assignment Operations.

Mutable vs Immutable Arguments

def modify_list(lst):
    lst.append(4)     # mutates the SAME object the caller has

def modify_int(n):
    n += 1             # rebinds the LOCAL name n -- caller's variable is untouched
    return n

>>> l = [1, 2, 3]
>>> modify_list(l)
>>> l                  # caller's list WAS mutated
[1, 2, 3, 4]

>>> num = 5
>>> result = modify_int(num)
>>> num, result         # caller's int was NOT changed; a new value was returned instead
(5, 6)

Return Values

Since reassignment inside a function never affects the caller’s variable for immutable types, the standard pattern is to explicitly return the new value and have the caller reassign it if needed — exactly as result = modify_int(num) does above.

Quick Interview Answer

“Python passes arguments by object reference — the parameter becomes a new name pointing at the same object the caller passed in. Whether the function’s changes are visible to the caller depends purely on mutability: mutating a mutable argument in place (lst.append(4)) is visible to the caller, since it’s the same object; reassigning an immutable argument (n += 1) just rebinds the local parameter name to a new object, leaving the caller’s variable untouched. That’s why functions dealing with immutable values follow the return-and-reassign pattern instead.”

Common Mistakes

  • Describing Python as “pass by value” or “pass by reference” — it’s neither; it’s pass-by-object-reference, and the visible behavior depends on the argument’s mutability.
  • Expecting a function like modify_int above to change the caller’s variable just because it looks similar to modify_list — only mutation is visible to the caller, not reassignment.
  • Relying on mutating a passed-in list as a way to “return” a result instead of using an explicit return — works, but is far less readable and easy to misuse.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form