class Dog:
# Class variable: shared by ALL dogs
species = 'Canis familiaris'
def __init__(self, name):
# Instance variable: unique to EACH dog
self.name = name
dog1 = Dog('Rex')
dog2 = Dog('Buddy')
# Instance variables are independent
dog1.name = 'Max'
print(dog1.name) # 'Max'
print(dog2.name) # 'Buddy' (unchanged)
# Class variable is shared
print(dog1.species) # 'Canis familiaris'
print(dog2.species) # 'Canis familiaris'# 1. Instance __dict__
# 2. Class __dict__
# 3. Parent class __dict__ (if inherited)
class Test:
x = 'Class Level'
def __init__(self):
self.x = 'Instance Level'
t = Test()
print(t.x) # 'Instance Level' (found here first!)
print(Test.x) # 'Class Level'
del t.x # Delete instance variable
print(t.x) # 'Class Level' (falls back to class!) # Mutable class variable (LIST)
items = []
def __init__(self, name):
self.name = name
a = Bad('A')
b = Bad('B')
a.items.append('apple') # Modifies the SHARED list!
print(b.items) # ['apple'] 🐛 Bug!Fix: Initialize mutable objects inside __init__
class Good:
def __init__(self, name):
self.name = name
self.items = [] # Fresh list for EACH instance
a = Good('A')
b = Good('B')
a.items.append('apple')
print(b.items) # [] (Safe!)class Circle:
PI = 3.14159
# 2. Counters
class User:
user_count = 0
def __init__(self, name):
self.name = name
User.user_count += 1
# 3. Caching/Shared state
class Config:
_settings = {}
@classmethod
def set(cls, key, val):
cls._settings[key] = valclass MyClass:
count = 0
def __init__(self):
# ⚠️ Ambiguous: creates INSTANCE variable if assigned!
# self.count = 1
def increment_bad(self):
self.count += 1 # Creates INSTANCE var, shadows CLASS var!
def increment_good(self):
MyClass.count += 1 # ✅ Correctly modifies CLASS var
@classmethod
def increment_cls(cls):
cls.count += 1 # ✅ Also correct, more flexibleCreate a `Circle` class with a class variable `PI = 3.14159` and an instance variable `radius`. Add methods `area()` and `circumference()` using `Circle.PI`. Then create a `BugDemo` class with a class variable `shared_list = []`. Show the bug: create two instances, append to one's list, and print the other's list. Then fix it by moving the list initialization to `__init__` in `FixedDemo`.