DEV Community

Cover image for Python Variables & Memory: The Deep-Dive Every Beginner Needs
Anik Sikder
Anik Sikder

Posted on

Python Variables & Memory: The Deep-Dive Every Beginner Needs

TL;DR

  • Variables in Python are names pointing to objects in memory, not boxes that store values.
  • CPython uses reference counting + a cycle-detecting garbage collector.
  • Mutable vs immutable objects change how reassignment and function calls behave.
  • Use == for value equality and is for identity checks.
  • CPython optimizes small ints and strings through interning and performs constant folding at compile time.

1) Variables Are Names, Not Boxes

Most beginners imagine variables as “containers” holding values. In Python, a variable is actually a name that references an object in memory.

Think: Name → Object (type, value, refcount)


2) Memory References in Python

Assigning a variable binds a name to an object:

x = 10
y = x   # y points to the same object as x

print(x, y)       # 10 10
print(id(x), id(y))  # same identity
Enter fullscreen mode Exit fullscreen mode

Rebinding creates a new link:

x = [1, 2, 3]
y = x
y.append(4)
print(x)  # [1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

Why it matters: Mutating objects via one name can affect other names referencing the same object.


3) Reference Counting in CPython

CPython tracks how many references point to an object. When the count hits 0, the object is deallocated.

import sys

a = [1, 2, 3]
print(sys.getrefcount(a))  # +1 due to temporary reference in function
b = a
print(sys.getrefcount(a))  # increased
del b
print(sys.getrefcount(a))  # back down
Enter fullscreen mode Exit fullscreen mode

Note: PyPy and other Python implementations use different GC strategies.


4) Garbage Collection & Cycles

Reference counting alone can’t reclaim cycles (A → B → A). Python’s cycle collector handles this:

import gc

class Node: 
    def __init__(self): self.ref = None

a, b = Node(), Node()
a.ref, b.ref = b, a
del a, b
collected = gc.collect()
print("Collected:", collected)
Enter fullscreen mode Exit fullscreen mode

Tip: Avoid __del__ in cyclic objects; it can delay collection.


5) Dynamic vs Static Typing

Python is dynamically typed (names can point to any type) and strongly typed (no silent coercion):

x = 10
x = "ten"    # fine
# x + 5      # TypeError
Enter fullscreen mode Exit fullscreen mode

Type hints help humans and IDEs, not the interpreter.


6) Variable Reassignment

Reassignment changes the binding, not the object:

x = 10
old_id = id(x)
x = 20
print(old_id == id(x))  # False
Enter fullscreen mode Exit fullscreen mode

For mutable objects, you can mutate or rebind:

nums = [1, 2]
nums = nums + [3]  # new list
nums.append(4)     # same list
Enter fullscreen mode Exit fullscreen mode

7) Mutability Explained

  • Immutable: int, float, bool, str, tuple, frozenset
  • Mutable: list, dict, set
s = "hi"
s += "!"       # new string object

d = {"a":1}
d["b"] = 2     # same dict object
Enter fullscreen mode Exit fullscreen mode

Tuples can contain mutable objects:

t = ([], 42)
t[0].append("boom")
print(t)  # (['boom'], 42)
Enter fullscreen mode Exit fullscreen mode

8) Functions, Arguments & Mutability

Python passes object references to functions:

def mutate(lst): lst.append(99)
def rebind(lst): lst = lst + [99]

a = [1, 2, 3]
mutate(a)   # [1, 2, 3, 99]
rebind(a)   # still [1, 2, 3, 99]
Enter fullscreen mode Exit fullscreen mode

Avoid mutable default arguments:

def good(x, bucket=None):
    if bucket is None:
        bucket = []
    bucket.append(x)
    return bucket
Enter fullscreen mode Exit fullscreen mode

9) Shared References Gotchas

Two names referencing the same mutable object share changes:

a = [1,2]; b = a; b.append(3)
print(a)  # [1,2,3]
Enter fullscreen mode Exit fullscreen mode

Copy carefully:

import copy
x = [[1],[2]]
y = copy.copy(x)      # shallow
z = copy.deepcopy(x)  # deep
Enter fullscreen mode Exit fullscreen mode

10) Equality: == vs is

  • == → value equality
  • is → identity (same object)
x = [1,2,3]; y = [1,2,3]
print(x==y, x is y)  # True, False

a = None; b = None
print(a is b)  # True
Enter fullscreen mode Exit fullscreen mode

Use is None for sentinel checks.


11) Everything is an Object

Names live in namespaces (dict-like):

x = 42
def f(): pass

print(type(x), type(f))
print(globals().keys())
Enter fullscreen mode Exit fullscreen mode

LEGB rule: Local → Enclosing → Global → Builtin


12) CPython Optimizations: Integer Interning

Small integers are often shared:

a = 256; b = 256
print(a is b)  # True

a = 257; b = 257
print(a is b)  # Might be False
Enter fullscreen mode Exit fullscreen mode

13) CPython Optimizations: String Interning

Compile-time literals and identifiers may be interned:

import sys
u = "".join(["status","_ok"])
v = "".join(["status","_ok"])
print(u is v)  # False
u = sys.intern(u); v = sys.intern(v)
print(u is v)  # True
Enter fullscreen mode Exit fullscreen mode

14) Constant Folding & Peephole Optimizations

Python precomputes simple expressions at compile-time:

x = 2*10     # folded to 20
y = ("a"+"b") # folded to "ab"
Enter fullscreen mode Exit fullscreen mode
import dis
def demo(): return 2*10
dis.dis(demo)
Enter fullscreen mode Exit fullscreen mode

Big-O matters more than peephole tricks.


Quick Checklist

  • [ ] Names point to objects, not values.
  • [ ] == for value, is for identity.
  • [ ] Mutables vs immutables.
  • [ ] Avoid mutable defaults.
  • [ ] Copy carefully (copy() vs deepcopy()).
  • [ ] Refcount + GC for cycles.
  • [ ] Interning is an optimization detail.
  • [ ] Clarity > micro-optimizations.

Wrap-Up

The golden rule: Python names point to objects. Once you internalize that, mutability, GC, equality, and optimization behavior all make sense.

Top comments (11)

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

Can I connected with you?

Collapse
 
anik_sikder_313 profile image
Anik Sikder

Yes Sure :)

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

do you have discord?

Thread Thread
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

Please tell me do you have discord, because Iam in a community of a developers.Thanks in advance.

Thread Thread
 
anik_sikder_313 profile image
Anik Sikder

Yep, I’m on Discord, happy to connect with you!
Here’s my username: anik7647
Feel free to add me anytime.

Thread Thread
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

ok.

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

I have a question please, do you work on python or in the programmation?Thanks in advance.

Collapse
 
anik_sikder_313 profile image
Anik Sikder

I’m working with Python and JS, great tools for web dev.

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

Ok.Thanks.

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

Good project and inspiration.

Collapse
 
sami_ammar_fb38e674b4a49e profile image
Sami Ammar

Do you have any community?Thanks in advance.