8. Classes & Objects
This is a big one — but it’s also the most powerful idea in the whole handbook. Take it slowly. Once it clicks, your evolution sim will make total sense.
The big idea: a blueprint and the things made from it
Imagine a cookie cutter. The cutter itself isn’t a cookie — it’s the shape that makes cookies. You can stamp out as many cookies as you like, and they all share the same shape, but each one is its own separate cookie.
In programming:
- The cookie cutter is a class — the blueprint.
- Each cookie is an object (also called an instance) — a real thing made from the blueprint.
For your sim, you’ll make a Creature class (the blueprint), and then create lots of creature objects from it. Each creature is separate, with its own energy and position, but they all follow the same blueprint.
The two things a class holds
A class describes two kinds of things about your object:
- Properties — the things an object has (its data). A creature has a name, energy, and speed. These are also called attributes.
- Methods — the things an object can do (its actions). A creature can move, eat, and have a baby. A method is just a function that lives inside a class.
Making your first class
Let’s build a Creature, one step at a time.
Step 1: the class and its setup
There’s a lot happening here, so let’s go through it slowly.
class Creature:— this starts the blueprint. Class names start with a Capital Letter (this is called PascalCase). That’s how you tell a class apart from a variable.def __init__(self, ...)— this special method is the setup instructions. It runs automatically every time you make a new creature. The name is__init__— that’s two underscores on each side. (People say it out loud as “dunder init”, short for “double underscore init”.) Its job is to get a fresh creature ready.self— this word means “this particular creature”. Since all creatures share the same blueprint,selfis how each one keeps track of its own data. Every method’s first parameter isself.self.name = name— this stores the name we were given onto this creature.self.energy = 100gives every new creature 100 energy to start. Theseself.somethingvalues are the properties (attributes) — the creature’s data.
Step 2: make some creatures
Now we use the blueprint to make real creatures:
When you write Creature("Spike", 5), Python runs __init__ for you, with name set to "Spike" and speed set to 5. (You never pass in self yourself — Python fills that in automatically.)
Now spike and bramble are two separate creature objects.
Step 3: read a creature’s properties
Use a dot . to reach a creature’s properties:
Output:
Each creature has its own data. Changing one doesn’t change the other:
Adding methods (things the creature can DO)
A method is a function inside the class. Its first parameter is always self, so it can see and change this creature’s own data.
Let’s give our creature the ability to move and to eat:
Now watch a creature live its little life:
Output:
See how spike.move() used self inside the method to change Spike’s energy? When you call spike.move(), Python quietly sends spike in as self. That’s the magic link.
A method that answers a question
Methods can return answers, just like normal functions:
Output:
Why this is perfect for an evolution sim
Here’s where it all comes together. You keep all your creatures in a list, then use a for loop to make every one of them take a turn:
Output:
Look how tidy that is! Whether you have 3 creatures or 3,000, that same little loop handles them all. That’s the power of classes.
A quick word on the names
- Class names use Capitals:
Creature,FoodItem,World. - Property and method names use snake_case:
self.energy,def move(self):. selfis always the first parameter of every method.__init__has two underscores on each side.
✅ Quick recap
- A class is a blueprint; an object is a real thing made from it.
- Properties (attributes) are what an object has:
self.energy. - Methods are what an object can do:
def move(self):. __init__is the setup method that runs when you make a new object.selfmeans “this particular object” — it’s how each object keeps its own data.- Make an object with
spike = Creature("Spike", 5). - Reach its data with a dot:
spike.energy. - Keep many objects in a list and loop over them to make your world tick.