Concepts / Understanding Objects and Classes

Understanding Objects and Classes

A class is a template; the class keyword does not create an object. Objects are created by calling the class like a function.

  • Programming
Interactive lab

Try it: Classes, Instances and Attributes

How a class creates instances with __init__ and self, why an attribute read checks the instance's __dict__ before the class, why assigning through an instance never changes the class, how a class-level list is shared by every instance, and why obj.method(x) is Class.method(obj, x).

How it works

  1. Dog(...) makes a new, empty instance and calls Dog.__init__(new_object, ...); self.name = ... stores into that object's __dict__.
  2. Reading obj.attr looks in obj.__dict__ first, then in the class.
  3. Assigning obj.attr = value always writes obj.__dict__, so it shadows a class attribute for that one object only.
  4. Mutating a class-level list (self.tricks.append) changes the one list every instance shares.
  5. obj.method is found on the class and bound to obj, so obj.method(x) runs Class.method(obj, x).

Default run (30 steps): Ready: class Dog and the statements you picked. Watch where each attribute is found and where each assignment writes. … Finished. Printed: ['sit'] / Wolf / Canis familiaris / Fido is 5.

Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Object numbers are illustrative, not real id() values.

Educational simulation

Loading the simulation…

Defining a Class Does Not Create an Object

Many learners look at a line such as class PartyAnimal: and assume it works like a function call that immediately produces something ready to use. The reason is understandable: in real programs, we write class PartyAnimal: and then right away use PartyAnimal. But the class keyword does not create an object at all. Before building anything else on classes, this distinction needs to be clear.

What do you think happens?

After Python runs the statement class PartyAnimal: and its indented body, does a PartyAnimal object now exist in memory, ready to use?

  • Yes, the class statement creates one ready-to-use object

  • No, the class statement only defines a template; an object appears only when the class is called

Reveal answer
Answer:

No, the class statement only defines a template; an object appears only when the class is called

The class keyword defines a template. It does not create an object by itself. Objects are created by calling the class like a function, such as PartyAnimal().

Templates and the Objects Built From Them

Definition

A class is a template defined using the class keyword. It describes the methods and the data layout that objects of that kind will have, but it is not itself an object. An object is a separate thing created by calling the class like a function. Each object created from a class has its own separate storage for data.

A useful way to hold this in mind is to treat the class as a blueprint and each object as a building constructed from it. One blueprint can be used to build several buildings, and each building is a separate physical thing. Changing one building does not change the others, even though they share a design. The diagram below shows this relationship: one class definition, with several objects that each come from it.

PartyAnimalclass templateanobjectbuddyobjectcreates an objectcreates an object
One class definition is the template. Each call to the class produces a separate object, and each object holds its own data.

Calling the Class to Create an Object

Creating an object means calling the class as if it were a function. When Python sees PartyAnimal(), it creates a new object from the template and then runs the special __init__ method on that new object. The sequence below traces what happens across the caller, the class, the new object, and __init__.

Calleryour codePartyAnimal classtemplatenew objectits own data storage__init__initial setup1. PartyAnimal()2. create object3. run on new object4. set self.x = 05. return object
Calling the class creates a new object, runs __init__ on that object, and returns the object to the caller.

Python runs __init__ automatically. You never call __init__ yourself in the usual case. Its job is to perform the initial setup of the data you want the object to carry. In the PartyAnimal class, __init__ creates an attribute called x using dot notation and sets it to zero. Because __init__ runs on every new object, every PartyAnimal object starts with x equal to 0.

Writing __init__ and a Regular Method

A class body contains methods. A method is a block of code that looks like a function: it starts with def and has an indented block. The difference is that every method has self as its first parameter. The example below shows a complete class with an __init__ method and a second method called party. The body of party is an illustrative choice made for this article; the important pattern is the shape of the definitions.

python
Output (expected)
So far 1
So far 2
Notes on the code
  • class PartyAnimal: defines the template; it creates nothing by itself
  • def __init__(self): is the constructor method that Python runs on each new object
  • self.x = 0 uses dot notation to give this object an attribute x set to zero
  • def party(self): is a regular method whose first parameter is self
  • an = PartyAnimal() calls the class, creating an object and running __init__
  • an.party() calls the method; Python passes an in as self
Code walkthrough
A class definition nests several parts. The outer element is the class name, PartyAnimal. Inside it sit the def blocks for __init__ and party, each of which is a method. Within __init__, the statement self.x = 0 creates an instance attribute on the object being initialized.
  1. 1
    The class line names the template. Nothing is created at this point.
  2. 2
    The __init__ method is defined with self as its first parameter. Python calls it on each new object.
  3. 3
    Inside __init__, self.x = 0 stores a value under the name x on that particular object.
  4. 4
    The party method is also defined with self first, so it can read and change the same object's data.
  5. 5
    Calling PartyAnimal() creates an object and runs __init__ on it.
  6. 6
    Calling an.party() runs the party body with self referring to the object an.

How self Connects Code to One Object

The self parameter is the bridge between the class template and the actual object. When you write self.x, you are saying the x attribute of this specific object. Without self, a method would have no way to know which object's data to read or change. You do not pass self yourself when you call the method. Python passes the object automatically.

This is why one method body can work on different objects. When you call an.party(), Python passes an as self, so inside party, self refers to an. When you call buddy.party(), Python passes buddy as self, so inside that same method body, self now refers to buddy. The code does not change between the two calls; only the object bound to self changes.

Several Objects With Separate State

A central benefit of classes is that many objects can come from one template while each keeps its own state. Both objects share the same method code, but their attribute values are stored separately. Modifying one object's attributes does not affect the other, because each object has its own storage in memory.

python
Output (expected)
So far 1
So far 2
So far 1
2 1
Notes on the code
  • an and buddy are two separate objects built from the same class
  • an.party() twice moves an.x up to 2
  • buddy.party() once moves only buddy.x up to 1
  • The final print shows each object's own value
an.x0an.x1buddy.x0buddy.x0
After an.party() runs, an.x changes from 0 to 1 while buddy.x stays at 0, because each object has its own x.
Worked example

Tracing two objects through the same method

Starting from a fresh PartyAnimal template, create two objects, call party on the first twice and on the second once, then find each object's x.

  1. 1
    Create an

    Calling PartyAnimal() creates an object and runs __init__, so an.x is 0.

  2. 2
    Create buddy

    A second call creates a second, separate object. __init__ runs again on it, so buddy.x is also 0.

  3. 3
    Call an.party() once

    Python passes an as self. Inside party, self.x = self.x + 1 reads an.x (0), adds 1, and stores 1 back into an.x.

  4. 4
    Call an.party() again

    Again self is an. an.x goes from 1 to 2.

  5. 5
    Call buddy.party() once

    Now self is buddy. buddy.x goes from 0 to 1. an.x is untouched and remains 2.

Result

an.x is 2 and buddy.x is 1. The same method code updated two different pieces of data.

Mistakes Beginners Make With Classes

  • Common mistake

    Expecting the class keyword to create an object

    What it looks like
    class PartyAnimal: followed by using a name that expects an object, with no call to PartyAnimal().
    Why it fails

    The class keyword only defines the template. No object exists until the class is called.

    Do this instead

    Create an object by calling the class: an = PartyAnimal().

  • Common mistake

    Leaving self out of the method definition or the attribute access

    What it looks like
    def party(): with x used directly instead of self.x.
    Why it fails

    Without self, the method has no way to know which object's data it should use, and the attribute is not tied to the object.

    Do this instead

    Write def party(self): and access data as self.x.

  • Common mistake

    Passing self manually when calling a method

    What it looks like
    an.party(an) in a call.
    Why it fails

    Python passes the object as self automatically. Adding it yourself is not how methods are called.

    Do this instead
    Call an.party() with no arguments.
  • Common mistake

    Assuming objects share their attribute values

    What it looks like

    Believing that after an.party(), buddy.x must also change.

    Why it fails

    Each object has its own storage for data, so changing one object's attributes does not affect another.

    Do this instead

    Check each object separately, as in the earlier example where an.x is 2 and buddy.x is 1.

Checking Your Understanding With a Practice Task

EASY

Using the PartyAnimal class from this article, create three objects named first, second, and third. Call party on second twice and on third once, leave first untouched, then print the x value of each object. Before running the code, predict each value.

Hints
  • Each call PartyAnimal() creates a new object and runs __init__ on it, so every object starts with x equal to 0.
  • A call such as second.party() passes second as self, so only second.x changes.
  • Predict first.x, second.x, and third.x before you run the code.

Key Takeaways

  • The class keyword defines a template and does not create an object; objects are created by calling the class like a function, such as PartyAnimal().
  • __init__ runs automatically on each new object and sets up its initial data using self, for example self.x = 0.
  • Every method has self as its first parameter; Python passes the object in automatically, so self.x refers to the x attribute of that specific object.
  • Objects built from the same class each keep separate storage for data, so changing one object's attributes does not change another's.

Related concepts

More concepts starting with U