Python Tutorial / Distinguish Instance Attributes from Class Attributes
Instance attributes hold object-specific data; class attributes can provide values shared through the class. Create each object’s mutable list during initialization when that list should be independent.
Locate the attribute to understand sharing
self.items stores an attribute on one instance. A list declared as items = [] in the class body belongs to the class and is shared by instances that do not have their own items attribute. Appending through one such instance can therefore affect the others.
An immutable default such as a currency label may be a class attribute. Assigning the same name through an instance can create an instance attribute that shadows the class value rather than updating the class itself.
For the relevant APIs and platform requirements, see Python: classes.
Name sharing and dataclass defaults build on the rules demonstrated in Create Data-Centered Classes with dataclass.
Run independent ledgers and a shadowed currency
Save the complete code below as attributes.py in a separate practice folder, using UTF-8. Run python attributes.py in a terminal with your project virtual environment selected. Outside a virtual environment on macOS or Ubuntu, use python3 when that is your interpreter command.
class Ledger:
currency = "KRW"
def __init__(self, owner):
self.owner = owner
self.items = []
def add(self, amount):
self.items.append(amount)
a = Ledger("A")
b = Ledger("B")
a.add(3500)
print(a.items, b.items)
b.currency = "USD"
print(a.currency, b.currency, Ledger.currency)
Expected output:
[3500] [] KRW USD KRW
Define initialization and later changes
Explicit initialization parameters describe the state required for a usable object. Saving an externally supplied list directly shares it with the caller; copy it only if independence is part of the contract. A shallow copy still shares nested mutable objects.
Changing Ledger.currency later does not necessarily affect every instance. In the sample, b has its own USD attribute and continues to use it. If shadowing makes the policy confusing, an explicit currency initialization parameter may be clearer.
A list defined in the class body is shared through the class. Create self.items = [] inside __init__ for independent per-instance lists. The following example compares one append becoming visible through another instance with properly separated storage.
Save the complete example as attributes.py and run python attributes.py in the same practice directory.
class Shared:
items = []
class Separate:
def __init__(self):
self.items = []
a, b = Shared(), Shared()
a.items.append(1)
print(a.items, b.items)
x, y = Separate(), Separate()
x.items.append(1)
print(x.items, y.items)
Expected output:
[1] [1] [1] []
Reproduce and repair accidental sharing
- Move items = [] into the class body and remove self.items = [] from __init__.
- Add through a and check that b sees the same list.
- Restore self.items = [] inside __init__ and confirm that the lists are independent again.
Shared collections can be intentional, but then lifetime and concurrent access require explicit design. Avoid using an accidentally shared class list as an informal global store. The aliasing and copy guide explains the same object-sharing principle outside classes.




