Question
Python Static Variables and Methods: Class Variables, @classmethod, and @staticmethod
Question
How can I create class-level variables and methods in Python?
I want to understand how to define variables that belong to the class itself rather than to each individual object, and how to create methods that can be called on the class without requiring an instance. In other words, how do class variables, @classmethod, and @staticmethod work in Python?
Short Answer
By the end of this page, you will understand how Python stores data on a class, how class variables differ from instance variables, and how to define methods that work at the class level using @classmethod and utility-style methods using @staticmethod. You will also see when to use each one and the mistakes beginners commonly make.
Concept
In Python, the phrase static variable is usually expressed as a class variable. A class variable is defined inside the class body and is shared by all instances of that class unless an instance overrides it.
A Python class can have three common kinds of members:
- Instance variables: belong to one object
- Class variables: belong to the class itself
- Methods: functions defined inside the class
And methods themselves can be of three main types:
- Instance methods: take
selfand work with one object - Class methods: take
clsand work with the class - Static methods: take neither
selfnorclsautomatically
Why this matters
This matters because real programs often need:
- shared configuration across all objects
- counters that track how many objects were created
- factory methods that construct objects in a standard way
- utility functions that logically belong inside a class
Class variables
A class variable is defined directly in the class:
class User:
role = "member"
Here, role belongs to User, not to any one object.
All instances can read it:
u1 = User()
u2 = User()
print(u1.role) # member
print(u2.role) # member
print(User.role) # member
Class methods
A class method uses the @classmethod decorator. Its first parameter is usually named cls, which refers to the class itself:
class User:
count = 0
@classmethod
def show_count(cls):
return cls.count
This is useful when a method needs to read or modify class-level data.
Static methods
A static method uses @staticmethod. It does not receive self or cls automatically:
class MathTools:
@staticmethod
def add(a, b):
return a + b
This is useful when the function belongs conceptually to the class, but does not need instance or class data.
Important Python idea
Python does not use a separate static keyword like Java or C#. Instead:
- use a class variable for shared class-level data
- use
@classmethodfor methods that work with the class - use
@staticmethodfor helper functions grouped inside the class
Mental Model
Think of a class as a building blueprint.
- An instance variable is furniture inside one specific apartment.
- A class variable is a sign posted on the building entrance that everyone in the building can see.
- An instance method is something one resident does inside their own apartment.
- A class method is something the building manager does for the whole building.
- A static method is like a rule sheet stored in the lobby: it belongs there, but it does not depend on any specific resident or even the manager.
So if data or behavior applies to the whole class, put it on the class. If it applies to one object, put it on the instance.
Syntax and Examples
Core syntax
Class variable
class Dog:
species = "Canis familiaris"
Instance variable
class Dog:
def __init__(self, name):
self.name = name
Class method
class Dog:
count = 0
@classmethod
def get_count(cls):
return cls.count
Static method
class Dog:
@staticmethod
def is_valid_name(name):
return len(name) > 0
Example: class variable and instance variable together
class Employee:
company = "Acme Inc."
def __init__(self, name):
self.name = name
emp1 = Employee("Alice")
emp2 = Employee("Bob")
print(emp1.name) # Alice
print(emp2.name) # Bob
print(emp1.company) # Acme Inc.
print(emp2.company) # Acme Inc.
print(Employee.company) # Acme Inc.
Explanation
nameis different for each employee, so it is an instance variable.companyis shared by all employees, so it is a class variable.
Example: counting created objects with a class method
class Employee:
count = 0
def __init__(self, name):
self.name = name
Employee.count += 1
@classmethod
def get_count(cls):
return cls.count
emp1 = Employee("Alice")
emp2 = Employee("Bob")
print(Employee.get_count()) # 2
print(emp1.get_count()) # 2
Explanation
countbelongs to the class.- Every time an
Employeeis created, the counter increases. get_count()reads class-level data usingcls.
Example: static method utility
class Temperature:
@staticmethod
def celsius_to_fahrenheit(c):
return (c * 9 / 5) + 32
print(Temperature.celsius_to_fahrenheit(25)) # 77.0
Explanation
This method is related to Temperature, but it does not need any object state or class state.
Step by Step Execution
Consider this example:
class Product:
tax_rate = 0.1
def __init__(self, name, price):
self.name = name
self.price = price
def total_price(self):
return self.price + (self.price * Product.tax_rate)
Now run:
p = Product("Book", 20)
print(p.total_price())
Step by step
1. Python reads the class definition
class Product:
Python creates the Product class object.
2. Python stores the class variable
tax_rate = 0.1
This value is attached to the class itself.
3. Python stores the methods
def __init__(self, name, price):
and
def total_price(self):
These functions become methods of the class.
4. An instance is created
p = Product("Book", 20)
Python creates a new object and calls __init__ with:
self= the new objectname="Book"price=20
5. Instance variables are assigned
self.name = name
self.price = price
Now the object p has:
p.name == "Book"p.price == 20
6. The method is called
p.total_price()
Python passes p as self.
7. The method uses instance and class data
return self.price + (self.price * Product.tax_rate)
self.pricecomes from the objectProduct.tax_ratecomes from the class
So the result is:
20 + (20 * 0.1) = 22.0
8. The final output is printed
22.0
This example shows that instance methods can access both instance data and class data.
Real World Use Cases
Shared settings
class AppConfig:
debug = True
version = "1.0"
Useful for values shared across the application.
Object counters
class Session:
active_sessions = 0
def __init__(self):
Session.active_sessions += 1
Useful for tracking how many objects have been created.
Factory methods
class User:
def __init__(self, username, active=True):
self.username = username
self.active = active
@classmethod
def guest(cls):
return cls("guest", active=False)
Useful when you want alternate ways to create objects.
Validation helpers
class Email:
@staticmethod
def is_valid(address):
return "@" in address
Useful when a helper function belongs with a class conceptually.
Data parsing
class Order:
def __init__(self, order_id, total):
self.order_id = order_id
self.total = total
@classmethod
def from_dict(cls, data):
return cls(data["order_id"], data["total"])
Useful when building objects from JSON, dictionaries, or API responses.
Real Codebase Usage
In real projects, developers commonly use these patterns:
Class variables for shared constants
class HTTPStatus:
OK = 200
NOT_FOUND = 404
These values are shared and do not change per instance.
Class methods as alternative constructors
class User:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_string(cls, text):
name, age = text.split(",")
return cls(name, int(age))
This pattern is common for parsing files, config values, or API input.
Guard clauses with validation
class User:
@staticmethod
def is_valid_age(age):
return age >= 0
def __init__(self, name, age):
if not self.is_valid_age(age):
raise ValueError("Age must be non-negative")
self.name = name
self.age = age
Static methods often support validation logic.
Using cls for inheritance-friendly code
class Animal:
@classmethod
def create(cls, name):
return cls(name)
Using cls(...) instead of Animal(...) means subclasses can inherit the method and still create the correct subclass type.
Keeping helper logic near the model
Developers sometimes place related utility functions inside a class with @staticmethod when the logic is closely tied to that class's purpose.
Common Mistakes
Mistake 1: Modifying a class variable through an instance by accident
class Item:
count = 0
item1 = Item()
item2 = Item()
item1.count = 5
print(item1.count) # 5
print(item2.count) # 0
print(Item.count) # 0
Why this happens
item1.count = 5 creates a new instance variable on item1. It does not change the class variable.
Better approach
Item.count = 5
or inside a class method:
@classmethod
def set_count(cls, value):
cls.count = value
Mistake 2: Using mutable class variables unintentionally
class Basket:
items = []
All instances share the same list, which is often not what beginners expect.
Broken behavior
b1 = Basket()
b2 = Basket()
b1.items.append("apple")
print(b2.items) # ['apple']
Fix
Use an instance variable if each object needs its own list:
class Basket:
def __init__(self):
self.items = []
Mistake 3: Forgetting decorators
class Example:
def greet():
return "hello"
Calling Example.greet() may work in some limited cases, but this is unclear and usually wrong for object-oriented design.
Fix
Use @staticmethod if no self or cls is needed:
class Example:
@staticmethod
def greet():
return "hello"
Mistake 4: Using self when cls is needed
class Counter:
total = 0
def increment(self):
self.total += 1
This may create or modify an instance variable instead of changing the shared class value.
Better approach
class Counter:
total = 0
@classmethod
def increment(cls):
cls.total += 1
Mistake 5: Using @staticmethod when inheritance-aware construction is needed
If a method needs to create objects of the current class, use @classmethod, not @staticmethod.
class Person:
@classmethod
def anonymous(cls):
return cls("Anonymous")
Comparisons
| Concept | Uses self? | Uses cls? | Access instance data? | Access class data? | Common use |
|---|---|---|---|---|---|
| Instance method | Yes | No | Yes | Yes | Work with one object |
| Class method | No | Yes | No | Yes | Shared behavior, alternate constructors |
| Static method | No | No | No | No, unless referenced manually | Utility function related to class |
Class variable vs instance variable
| Feature | Class variable | Instance variable |
|---|---|---|
| Belongs to | The class | One object |
| Shared? | Yes | No |
| Defined where? | In class body | Usually in __init__ with self |
| Typical use | Constants, counters, config | Per-object state |
@classmethod vs @staticmethod
| Feature | @classmethod | @staticmethod |
|---|---|---|
| First argument | cls | None automatic |
| Knows which class called it? | Yes | No |
| Good for constructors? | Yes | No |
| Good for utility helpers? | Sometimes | Yes |
Quick rule
- Use an instance method if you need
self - Use a class method if you need
cls - Use a static method if you need neither
Cheat Sheet
Quick reference
Class variable
class MyClass:
shared_value = 10
- Shared by all instances
- Access with
MyClass.shared_value - Can also be read through instances
Instance variable
class MyClass:
def __init__(self, value):
self.value = value
- Separate for each object
Class method
class MyClass:
@classmethod
def my_method(cls):
return cls
- Receives the class as
cls - Useful for shared logic and factory methods
Static method
class MyClass:
@staticmethod
def helper(x, y):
return x + y
- Receives no automatic first argument
- Useful for helper functions tied to the class
Rules to remember
- Python does not use a
statickeyword for class variables - Class variables are defined directly in the class body
- Use
@classmethodwhen the method needs the class - Use
@staticmethodwhen the method needs neither class nor instance - Avoid mutable class variables unless sharing is intentional
Common pattern
class User:
count = 0
def __init__(self, name):
self.name = name
User.count += 1
@classmethod
def total_users(cls):
return cls.count
@staticmethod
def valid_name(name):
return len(name.strip()) > 0
Edge case
This creates an instance attribute, not a class update:
obj.count = 99
To update the class variable, use:
ClassName.count = 99
FAQ
What is the Python equivalent of a static variable?
In Python, the equivalent is usually a class variable, defined directly inside the class body.
How do I create a static method in Python?
Use the @staticmethod decorator:
class Example:
@staticmethod
def hello():
return "hello"
What is the difference between @classmethod and @staticmethod in Python?
A class method receives cls and can access class state. A static method receives no automatic argument and behaves like a regular function stored inside the class.
Can a class method change a class variable?
Yes. That is one of its main uses.
@classmethod
def set_value(cls, value):
cls.some_value = value
Can an instance access a class variable?
Yes. An instance can read a class variable unless that name is overridden on the instance itself.
Why does changing a class list affect all objects?
Because a mutable class variable, like a list or dictionary, is shared by all instances.
Should I use @staticmethod a lot?
Only when the function clearly belongs with the class but does not need self or cls. Otherwise, a module-level function may be simpler.
Can I call a class method on an instance?
Yes, but conceptually it belongs to the class. It is often clearer to call it on the class name.
Mini Project
Description
Build a small BankAccount class to practice class variables, class methods, and static methods together. This project demonstrates a realistic pattern: tracking shared information across all accounts, creating objects in different ways, and validating input with helper logic.
Goal
Create a Python class that tracks the number of bank accounts, stores per-account data, and provides a utility method for validating deposit amounts.
Requirements
- Create a
BankAccountclass with an account holder name and balance. - Add a class variable that counts how many accounts have been created.
- Add a class method that returns the total number of accounts.
- Add a static method that checks whether a deposit amount is valid.
- Add a
deposit()instance method that uses the validation logic.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.