How do you define a class in Python, and what is the role of `__init__`?
A class in Python is defined using the class keyword. The __init__ method is the initializer (often called the constructor, though technically __new__ is the true constructor). It is called automatically when a new instance is created, and its primary purpose is to set up the instance's initial state by assigning attributes.
The first parameter of __init__ is always self, which refers to the newly created instance. Through self, you attach attributes that are unique to each instance.
Key distinctions:
__new__creates the instance (allocates memory)__init__initializes the instance (sets attributes)__init__must returnNone(implicitly)- If
__init__is not defined, instances are created with no custom initialization
1. Use 'class ClassName:' to define a class
2. Define __init__(self, params) to initialize attributes
3. Use self.attribute = value to set instance attributes
4. Create instance: obj = ClassName(args)
5. Python calls __new__ then __init__ automatically
class Dog:
# Class attribute -- shared by all instances
species = "Canis familiaris"
def __init__(self, name, age, breed):
"""Initialize a Dog instance."""
# Instance attributes -- unique to each instance
self.name = name
self.age = age
self.breed = breed
self.tricks = [] # mutable default per instance
def bark(self):
return f"{self.name} says Woof!"
def learn_trick(self, trick):
self.tricks.append(trick)
return f"{self.name} learned {trick}"
# Creating instances
rex = Dog("Rex", 3, "German Shepherd")
buddy = Dog("Buddy", 5, "Golden Retriever")
print(rex.bark()) # Rex says Woof!
print(buddy.bark()) # Buddy says Woof!
print(rex.species) # Canis familiaris (class attribute)
# Each instance has its own tricks list
rex.learn_trick("sit")
print(rex.tricks) # ['sit']
print(buddy.tricks) # [] -- separate list
# Instance attributes vs class attributes
print(rex.__dict__) # {'name': 'Rex', 'age': 3, 'breed': 'German Shepherd', 'tricks': ['sit']}
print(Dog.__dict__) # includes 'species', '__init__', 'bark', etc.
# What happens without __init__
class Empty:
pass
e = Empty()
e.x = 10 # attributes can still be added dynamically
print(e.x) # 10
- •__init__ initializes instance attributes via self.attr = value
- •self refers to the current instance being created
- •Class attributes are shared, instance attributes are per-instance
- •__init__ is called automatically after __new__ creates the instance
- •__init__ must return None -- returning anything else raises TypeError
- •Mutable default arguments in __init__ signature (def __init__(self, items=[])) are shared across calls -- use None and create inside
- •Forgetting self in __init__ creates a local variable, not an instance attribute