Lesson 8 · 8 of 20
Classes and objects · Python
Object-oriented programming in Python: classes, __init__, self, attributes, methods, properties and __str__, with players in a role-playing game.

A class is a mould and each object (or instance) is a piece made from it. Player("Aria", attack=35) creates a new player: Python makes the object and calls `__init__`, which fills in its data.
The first parameter of every method, `self`, is the object itself. self.name = name creates an instance attribute: each player has its own. max_health, on the other hand, sits in the class body and is a class attribute, shared by all of them (Player.max_health).
Methods are functions that work on the object. hit(self, other) takes another player and lowers their health, never below zero thanks to max(0, ...); pick_up adds items to the inventory list, which also belongs to each player because it is created in __init__.
@property turns alive into a computed value you read like an attribute, without parentheses: while orc.alive: keeps hitting until the orc runs out of health. __str__ decides how the object looks in print().
The last line separates two ideas: hero and orc have the same type (type(hero) is type(orc)), but they are different objects (hero is orc is False).
Code · main.py
class Player: """A player in a small role-playing game.""" max_health = 100 # class attribute: shared by all def __init__(self, name, attack): self.name = name # instance attributes: one per object self.attack = attack self.health = Player.max_health self.inventory = [] def hit(self, other): other.health = max(0, other.health - self.attack) print(f"{self.name} hits {other.name}: {other.health} HP left") def pick_up(self, item): self.inventory.append(item) @property def alive(self): # used like an attribute, no () return self.health > 0 def __str__(self): return f"{self.name} ({self.health}/{self.max_health} HP)"hero = Player("Aria", attack=35)orc = Player("Grok", attack=20)hero.pick_up("potion")while orc.alive: hero.hit(orc)print(hero, "| inventory:", hero.inventory)print(orc, "| alive:", orc.alive)print("Same class:", type(hero) is type(orc), "| same object:", hero is orc)Output · python3 main.py
Aria hits Grok: 65 HP left Aria hits Grok: 30 HP left Aria hits Grok: 0 HP left Aria (100/100 HP) | inventory: ['potion'] Grok (0/100 HP) | alive: False Same class: True | same object: False
Key points
classdefines the mould;Class(...)creates an object.__init__sets up each new object;selfis that object.- Attributes on
selfbelong to each object; those in the class body are shared. @propertyexposes a calculation as if it were an attribute.__str__controls whatprint()shows.
Exercise
Add a heal(amount) method that raises health without going past max_health, and make Grok heal 20 points after the second hit.