Quick answer: Python has no static variable keyword for ordinary local variables. A class attribute can provide shared class-level state, while instance attributes provide per-object state; choose the location deliberately and avoid mutable class attributes when instances should be independent.

Python does not use the same static-field model found in languages such as Java or C++. The closest everyday tool is a class attribute: a name stored on the class object itself. Instances can read it through normal attribute lookup, and all instances see the same class-level value until one instance shadows that name with its own attribute.
This distinction matters because class attributes are convenient for constants, counters, labels, feature flags, caches, and defaults, but they can also surprise readers when used for data that should belong to one object. The official Python classes tutorial explains class and instance attributes, while the Python data model documentation explains attribute access rules.
The practical rule is simple: put shared facts on the class, put per-object data on the instance, and be especially careful with mutable objects. If a list, dictionary, or set should be separate for each object, create it inside __init__.
Store Shared Data On The Class
A class attribute is written directly in the class body. Each instance can read it, and the class can read it too.
class Counter:
total = 0
def __init__(self):
Counter.total += 1
first = Counter()
second = Counter()
print(Counter.total)
print(first.total)
print(second.total)
Both objects read the same class-level total. The constructor updates Counter.total, so the count is shared across every new object created from that class.
This pattern is useful when the value truly belongs to the class as a whole. Common examples include a registry count, a default timeout, a label used by every instance, or a simple flag that controls class-wide behavior.
Know How Lookup Works
When Python evaluates obj.name, it checks the instance first. If that name is not stored on the instance, Python then looks at the class and base classes.
class Theme:
color = "blue"
main = Theme()
preview = Theme()
main.color = "green"
print(main.color)
print(preview.color)
print(Theme.color)
The assignment to main.color creates an instance attribute on only that object. It does not change Theme.color, so preview still reads the class-level default.
This shadowing is not a bug. It is normal attribute lookup. Trouble starts when a reader expects an assignment through one instance to update shared class data. To update shared data, assign through the class name or use a class method that makes the intent clear.
Avoid Shared Mutable Defaults
Mutable class attributes are the common footgun. A list stored on the class is one list, not a fresh list per object.
class Basket:
items = []
def add(self, item):
self.items.append(item)
first = Basket()
second = Basket()
first.add("apple")
second.add("pear")
print(first.items)
print(second.items)
Both objects show both items because both objects reached the same list. The method does not assign a new list; it mutates the shared list in place.
Shared mutable data can be correct for an intentional cache or registry, but it should be named and documented like shared state. For normal object data, prefer an instance attribute.
Create Per-Object Data In __init__
Use __init__ when each object should get its own list, dictionary, counter, or other changing state.
class Basket:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
first = Basket()
second = Basket()
first.add("apple")
second.add("pear")
print(first.items)
print(second.items)
Now each object owns a separate items list. The method can mutate self.items without affecting another instance.
This is the safer default for user data, request data, parsed records, carts, game state, and any other value that changes independently per object.
Use Class Methods For Shared Updates
A class method receives the class as cls. That makes it a good place to update shared class attributes without hard-coding the class name.
class FeatureFlag:
enabled = False
@classmethod
def turn_on(cls):
cls.enabled = True
@classmethod
def turn_off(cls):
cls.enabled = False
FeatureFlag.turn_on()
print(FeatureFlag.enabled)
FeatureFlag.turn_off()
print(FeatureFlag.enabled)
The method writes through cls, so subclasses can participate in the same pattern. This is clearer than assigning through a random instance because the method name says the operation targets class-level state.
Use class methods for alternate constructors, counters, shared configuration, and explicit class-wide state changes. Use instance methods when the operation depends on one object.
Understand Inheritance Defaults
Class attributes follow normal inheritance. A subclass can reuse a default from a base class or replace it with a more specific value.
class BaseClient:
timeout = 30
class ApiClient(BaseClient):
timeout = 10
class BatchClient(BaseClient):
pass
print(ApiClient.timeout)
print(BatchClient.timeout)
print(BaseClient.timeout)
ApiClient defines its own timeout, while BatchClient inherits the base default. This makes class attributes useful for configuration defaults that differ by subclass.
Be careful when mutating inherited mutable data. If a subclass only reads an inherited list, it sees the base list. If it needs its own list, define a new list on the subclass or create per-object data in __init__.
When To Use This Pattern
Class attributes are a good fit for constants, default settings, simple shared counters, names used by every instance, and data that describes the class rather than one object. They keep shared facts close to the class that owns them.
Avoid class attributes for changing user data unless the sharing is deliberate. If two instances should be able to change independently, store the value on self. If shared state is required, make updates explicit with class methods and tests.
The best test is to create two instances and change one. If the other should not change, the data belongs on the instance. If both should see the same state, a class attribute may be the right tool.
Keep names plain and direct. A name such as default_timeout, enabled, or kind tells readers whether the value is a default, a flag, or a descriptor. Good naming matters because class-level state affects every object that reads it.
In production code, treat shared mutable state as a design choice. It can be fast and convenient, but it also increases coupling between tests and between parts of an application. Reset shared state in tests, or better, avoid it unless the class really owns that state.
Distinguish The Storage Locations
A local variable belongs to one call, an instance attribute belongs to one object, and a class attribute is looked up through the class and instances. Naming these lifetimes makes the design easier to review.
Use Class Attributes For Shared Defaults
Class attributes are appropriate for immutable configuration, shared constants, or metadata that genuinely belongs to the class. An instance assignment with the same name shadows the class value.
Initialize Mutable State Per Instance
Lists, dictionaries, caches, and sets placed on the class are shared by every instance. Create them in __init__ when each object needs an independent collection.
Choose A Clear Counter Pattern
For counts, decide whether the value is global to a class, belongs to each instance, or should be managed by an external service. Hidden shared counters can create test-order and concurrency problems.
Use Class Methods Deliberately
A class method receives the class as cls and can update class-level state, but that does not make the state automatically thread-safe or process-wide. Document synchronization and inheritance behavior.
Test Sharing And Isolation
Create multiple instances and assert the intended sharing behavior, subclass overrides, reset behavior, concurrent access policy, serialization, and cleanup. Tests should make accidental shared mutation obvious.
Use the official Python classes documentation for class and instance attributes. Related Python Pool references include tests and mapping state.
For related state design, compare isolation tests, shared mappings, and mutable sequences before placing data on a Python class.
Frequently Asked Questions
Does Python have static variables?
Python has no static variable keyword for local variables, but class attributes can hold values shared through a class and its instances.
What is the difference between a class and instance attribute?
A class attribute is looked up on the class and can be shared, while an instance attribute is stored on one object and normally shadows a class attribute with the same name.
How do I create a static variable in a Python function?
A function attribute can store state, but a class, closure, or explicit object is usually clearer and easier to test than hidden mutable function state.
Should I use class attributes for mutable data?
Use caution. A mutable class attribute is shared by instances, so initialize per-instance collections in __init__ when each object needs independent state.
Why do you call class attributes static variables? And you missed the main point, modifying a class variable changes its state for every single instance of that class.
The reason behind calling the static variable as a class variable was because it is valid to all the objects of the class as it being a class-level variable.
Hope that helps.