Learning

Classes & Objects

Classes & Objects

Defining a Class

python
# Class attribute (shared by all instances) species = 'Canis familiaris' # Constructor (initializer) def __init__(self, name, age): # Instance attributes (unique to each object) self.name = name self.age = age # Instance method def bark(self): return f'{self.name} says Woof!' def get_older(self): self.age += 1

Creating Objects (Instances)

python
dog2 = Dog('Buddy', 5) print(dog1.name) # 'Rex' print(dog2.name) # 'Buddy' print(dog1.bark()) # 'Rex says Woof!' # Class attribute accessed via instance or class print(dog1.species) # 'Canis familiaris' print(Dog.species) # 'Canis familiaris'

Understanding 'self'

python
# Python passes it automatically when you call a method dog1.bark() # Python internally translates this to: Dog.bark(dog1) # You can name it anything, but 'self' is the universal convention class Bad: def __init__(this_is_weird, val): # Works, but don't do this! this_is_weird.val = val

Dynamic Attributes

python
class User: pass u = User() u.name = 'Alice' # Adding attribute on the fly! u.email = 'alice@test.com' # ⚠️ Dangerous: another instance won't have these u2 = User() # print(u2.name) # AttributeError!

Methods Types

python
# Instance method (takes self) def add(self, a, b): return a + b # Class method (takes cls, used for alternative constructors) @classmethod def from_string(cls, math_string): a, b = map(int, math_string.split('+')) return cls(a, b) # Returns instance # Static method (no self or cls, just a namespaced function) @staticmethod def is_number(val): return isinstance(val, (int, float))

str and repr

python
def __init__(self, name): self.name = name def __str__(self): # User-friendly string (for print/display) return f'Person: {self.name}' def __repr__(self): # Developer-friendly string (for debugging) return f'Person({self.name!r})' p = Person('Alice') print(p) # Person: Alice (calls __str__) print(repr(p)) # Person('Alice') (calls __repr__) print([p]) # [Person('Alice')] (lists use __repr__)
Key Rules
  • •__init__ is NOT a constructor — it's an initializer. The object is already created by __new__ before __init__ runs
  • •self must be the FIRST parameter of any instance method — Python passes the instance automatically
  • •Class attributes are shared across ALL instances; instance attributes (self.x) are unique to each object
  • •Always implement __repr__ for your classes — it saves hours of debugging by showing useful info
  • •Use @staticmethod for utility functions that don't need class/instance data, @classmethod for factory methods
Your Task

Create a `Car` class with `make`, `model`, and `year` instance attributes, and a class attribute `total_cars = 0`. The `__init__` should increment `total_cars`. Add methods `describe()` (returns a string), `update_mileage(self, miles)` (adds to `self.mileage`), and `__repr__()`. Create 2 cars, describe them, update mileage, and print `Car.total_cars`.

EditorPython · JSX
PreviewUpdates on Run Tests
Loading preview…
Tests
Should define Car class
Should have class attribute total_cars
Should increment total_cars in __init__
Should implement __repr__ method
Should create at least 2 Car instances
Should call describe and update_mileage