correct way to define class variables in Python
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
In Python, class variables are defined inside the class body but outside any method. They are shared across all instances. Instance variables are defined in __init__ using self.name = value and are unique to each instance. The critical rule is: never mutate a mutable class variable (like a list or dict) through an instance — it modifies the shared object. Use class variables for constants and defaults, and instance variables for per-object state.
Class Variables vs Instance Variables
The Mutable Class Variable Trap
The fix — initialize mutable data in __init__:
Assignment Creates Instance Variables
When you assign to self.x, Python creates an instance variable that shadows the class variable:
When to Use Class Variables
Class Variables with Type Hints
Using slots with Class Variables
Accessing Class Variables
Common Pitfalls
- Defining mutable default values as class variables: Lists, dicts, and sets defined as class variables are shared across all instances. Appending to
self.itemsmutates the shared object. Always initialize mutable data in__init__withself.items = []. - Using
self.class_var += 1instead ofClassName.class_var += 1: For immutable types likeint,self.count += 1creates a new instance variable that shadows the class variable. The class variable remains unchanged. UseClassName.count += 1to modify the shared value. - Assuming class variable changes propagate to existing instances: If an instance has already created a shadowing instance variable (via assignment), changing the class variable does not affect that instance. The instance variable takes priority in the MRO lookup.
- Not using
ClassVartype annotation for type checkers: WithoutClassVar, type checkers like mypy may treat class variables as instance variables. Usetyping.ClassVar[T]to explicitly mark shared state. - Confusing class variables with
__init__defaults:def __init__(self, items=[])is a different problem (mutable default argument) but produces the same shared-state bug. The default list is created once and shared across all calls. Usedef __init__(self, items=None): self.items = items or [].
Summary
- Define class variables in the class body (outside methods) for shared constants and counters
- Define instance variables in
__init__withself.name = valuefor per-object state - Never use mutable class variables (lists, dicts) for per-instance data — initialize them in
__init__ - Modify class variables via
ClassName.var, notself.var, to avoid creating instance shadows - Use
typing.ClassVar[T]to annotate class variables for type checkers
Related reading
- Correct way to pause a Python program
- Correct way to try/except using Python requests module?
- Correct way to write line to file?
- Cost of len function
- Could not convert string to float error from the Titanic competition
- Could not find a version that satisfies the requirement package
- Could not find a version that satisfies the requirement tensorflow
- Could not find a version that satisfies the requirement tensorflow
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack 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.