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.
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
- Dog(...) makes a new, empty instance and calls Dog.__init__(new_object, ...); self.name = ... stores into that object's __dict__.
- Reading obj.attr looks in obj.__dict__ first, then in the class.
- Assigning obj.attr = value always writes obj.__dict__, so it shadows a class attribute for that one object only.
- Mutating a class-level list (self.tricks.append) changes the one list every instance shares.
- 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.
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?
Reveal 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
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.
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__.
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.
So far 1
So far 2- 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
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.- 1The class line names the template. Nothing is created at this point.
- 2The
__init__method is defined with self as its first parameter. Python calls it on each new object. - 3Inside
__init__,self.x= 0 stores a value under the name x on that particular object. - 4The party method is also defined with self first, so it can read and change the same object's data.
- 5Calling
PartyAnimal()creates an object and runs__init__on it. - 6Calling
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.
So far 1
So far 2
So far 1
2 1- an and buddy are two separate objects built from the same class
an.party()twice movesan.xup to 2buddy.party()once moves onlybuddy.xup to 1- The final print shows each object's own value
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.
- 1Create an
Calling
PartyAnimal()creates an object and runs__init__, soan.xis 0. - 2Create buddy
A second call creates a second, separate object.
__init__runs again on it, sobuddy.xis also 0. - 3Call an.party() once
Python passes an as self. Inside party,
self.x=self.x+ 1 readsan.x(0), adds 1, and stores 1 back intoan.x. - 4Call an.party() again
Again self is an.
an.xgoes from 1 to 2. - 5Call buddy.party() once
Now self is buddy.
buddy.xgoes from 0 to 1.an.xis untouched and remains 2.
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 likeclass PartyAnimal: followed by using a name that expects an object, with no call to PartyAnimal().Why it failsThe class keyword only defines the template. No object exists until the class is called.
Do this insteadCreate an object by calling the class: an = PartyAnimal().
Common mistake Leaving self out of the method definition or the attribute access
What it looks likedef party(): with x used directly instead of self.x.Why it failsWithout 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 insteadWrite def party(self): and access data as self.x.
Common mistake Passing self manually when calling a method
What it looks likean.party(an) in a call.Why it failsPython passes the object as self automatically. Adding it yourself is not how methods are called.
Do this insteadCall an.party() with no arguments.Common mistake Assuming objects share their attribute values
What it looks likeBelieving that after an.party(), buddy.x must also change.
Why it failsEach object has its own storage for data, so changing one object's attributes does not affect another.
Do this insteadCheck 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
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 onlysecond.xchanges. - Predict
first.x,second.x, andthird.xbefore 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 exampleself.x= 0.- Every method has self as its first parameter; Python passes the object in automatically, so
self.xrefers 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.