Instance vs Class Variables
Every Python class can have two different kinds of attributes: class variables, which are shared by every instance of the class, and instance variables, which belong to one specific object. Mixing these up is one of the most common sources of confusing bugs for people learning object-oriented Python, so it is worth understanding exactly where each one lives and how Python decides which one you are talking about.
Class variables
A class variable is defined directly inside the class body, outside of any method (including __init__). It is created once, when the class itself is defined, and it is shared by every instance of that class. If one instance changes the underlying class variable through the class itself, every other instance sees the new value, because there is really only one copy of it.
Instance variables
An instance variable is specific to a single object. It is usually created inside __init__ (or any other method) by assigning to self.something. Each object gets its own independent copy: setting it on one instance has no effect on any other instance.
class Dog:
# Class variable: shared by every Dog instance
species = "Canis familiaris"
def __init__(self, name):
# Instance variable: unique to each Dog
self.name = name
rex = Dog("Rex")
fido = Dog("Fido")
print(rex.name, rex.species)
print(fido.name, fido.species)
# Both instances share the exact same class variable
print(rex.species is fido.species)Rex Canis familiaris Fido Canis familiaris True
Notice that name is different for each dog, while species is the same value for both — because both rex.species and fido.species actually resolve to the single Dog.species class attribute.
Accessing class variables: ClassName vs instance
You can read a class variable either through the class itself (Dog.species) or through any instance (rex.species). When you read rex.species, Python first looks for species on the rex instance; it doesn't find one, so it falls back to looking on the Dog class and finds it there. This lookup order — instance first, then class — is exactly what causes the subtle bug described below.
Writing is different from reading. If you assign self.species = "X" inside a method, Python does not modify Dog.species. Instead, it creates a brand-new instance variable called species on that one object, which then shadows (hides) the class variable for that instance only.
rex.species = "Wolf (mutant)" print(rex.species) # instance variable, just created print(fido.species) # unaffected, still reads the class variable print(Dog.species) # the class variable itself never changed
Wolf (mutant) Canis familiaris Canis familiaris
The classic mutable class variable bug
The most common mistake is using a mutable object — a list, dict, or set — as a class variable, expecting it to act as an empty starting point for each instance. Because the class variable is shared, every instance that mutates it in place (with .append, .update, and so on) is actually mutating the same shared object.
class ShoppingCart:
# BUG: this list is a class variable, not an instance variable
tags = []
def __init__(self, owner):
self.owner = owner
def add_tag(self, tag):
self.tags.append(tag) # mutates the *shared* class list
cart_a = ShoppingCart("Alice")
cart_b = ShoppingCart("Bob")
cart_a.add_tag("books")
cart_b.add_tag("electronics")
print(cart_a.tags)
print(cart_b.tags)
print(cart_a.tags is cart_b.tags)['books', 'electronics'] ['books', 'electronics'] True
Both carts show both tags, and cart_a.tags is cart_b.tags is True — they are literally the same list object. self.tags.append(...) never assigns to self.tags, so Python never creates an instance variable; it just keeps mutating ShoppingCart.tags through whichever instance happens to call the method.
The fix is to create a genuine instance variable in __init__, so each object gets its own independent list:
class ShoppingCart:
def __init__(self, owner):
self.owner = owner
self.tags = [] # FIX: a fresh list per instance
def add_tag(self, tag):
self.tags.append(tag)
cart_a = ShoppingCart("Alice")
cart_b = ShoppingCart("Bob")
cart_a.add_tag("books")
cart_b.add_tag("electronics")
print(cart_a.tags)
print(cart_b.tags)
print(cart_a.tags is cart_b.tags)['books'] ['electronics'] False
When to use which
A simple way to decide: ask whether the value describes the type of thing or this particular object.
Class variable: constants, configuration shared by all instances, or counters that track something about the class as a whole (for example,Dog.species,MAX_CONNECTIONS = 10, or atotal_createdcounter incremented in__init__).Instance variable: any state that differs from object to object — a name, an id, a running total, a list of items that belongs to this object and not to others.
Class variable | Instance variable | |
|---|---|---|
Defined | In the class body, outside methods | Inside a method via |
Shared across instances? | Yes — one copy for the whole class | No — one copy per object |
Accessed via |
|
|
Assigning | Creates a new instance variable, shadows the class one | Updates that instance only |
Best for | Constants, shared config, defaults | Per-object state |