Coding Python
Home›Python Coding Games›Creature Lab

Creature Lab — Classes & objects

Six specimens built from scratch — blueprint first, then spawn from it.

6 levels · Intermediate
Level 1

Checks
    Your PythonPython 3
    1

    How to play

    Each level gives you a specification: expressions on the left, the value each should produce on the right. Write the class, press Run, and every row is ticked individually — so a class that works for one creature and quietly shares state between two tells you exactly which case broke.

    What each level teaches

    1. The blueprint — class, __init__ and self.
    2. Teach it a trick — methods, and how they reach their own data.
    3. Take a hit — changing an object's state rather than returning a new one.
    4. Make it printable — __str__, instead of <__main__.Creature object at 0x7f…>.
    5. Count the specimens — a class attribute, shared by every instance.
    6. Are they the same? — __eq__, and what == means by default.

    What self actually is

    It is not a keyword and there is nothing magic about the name. When you call sparky.describe(), Python calls Creature.describe(sparky) — the object is passed in as the first argument, and self is just the conventional name for it. That is why every method needs it in the signature, and why forgetting it gives you "takes 0 positional arguments but 1 was given", which is one of the most confusing error messages a beginner meets.

    The trap in level 5

    Level 1 already checks that two creatures have independent hp, and level 5 is the mirror image:

    • self.count = … creates an attribute on that one object. Every creature gets its own, so the total is always 1.
    • Creature.count = … changes the attribute on the class, which every instance shares.

    Reading is the confusing part: self.count reads the class attribute perfectly well if no instance attribute exists. So the count appears to work until something writes to it through self, and from that moment the two silently diverge.

    Dunder methods are hooks, not decoration

    __str__ and __eq__ are not special-cased by the language — they are how Python asks your object a question. print(x) calls __str__, x == y calls __eq__, len(x) calls __len__, for i in x calls __iter__. Implement the hook and your class works with the ordinary syntax everyone already knows. The written version, including properties and dataclasses, is in the tutorial on Python classes and objects.

    Practise classes & objects on your phone — the Coding Python app runs real Python 3 on your phone, with examples, quizzes and challenges built in.
    Get it free

    Frequently asked questions

    What is self in Python?

    The instance the method was called on, passed in as the first argument. sparky.describe() is really Creature.describe(sparky). The name is convention, not a keyword.

    What is the difference between a class attribute and an instance attribute?

    A class attribute is defined in the class body and shared by every instance. An instance attribute is set through self, usually in __init__, and belongs to that one object.

    What does __init__ do?

    It runs immediately after an object is created, and is where you store the values that object needs. It is not a constructor in the strict sense — the object already exists by then.

    Why does printing my object show something like <__main__.Dog object at 0x7f…>?

    Because the class has no __str__. Define one returning readable text and print() will use it.

    What is the difference between == and is?

    == asks whether two things are equal, and calls __eq__ if you defined one. is asks whether they are the very same object in memory. Without __eq__, == falls back to is.

    Keep going

    ← All Python coding games  Read the tutorial →

    Take the games with you

    Coding Python packs a real Python 3 compiler, 30 example programs, 112 quiz questions and 12 self-checking challenges into one free Android app.

    Get it on Google Play
    Coding Python app icon