Concepts / Designing Classes for Real-World Problems

Designing Classes for Real-World Problems

A class is a template that defines what data and code each object will have; the class keyword does not create an object.

  • Programming

A Template Is Not an Object

When you design a class, you describe the data and code that objects of that class will have. The class is a template, not an object. Writing the class keyword defines that template, but it does not by itself create an object. An object is created when the class is called as if it were a function.

PartyAnimaltemplateanx = 0anotherx = 0createscreates
What is the difference between a class template and the individual objects created from it?
In the real world

A useful analogy is a cookie cutter. The cutter describes the shape shared by the cookies, but the cutter is not itself a cookie. In the same way, a class describes the structure and behavior that its objects will have, while each object is an individual instance created from that template.

Creating an Initialized Object

Calling a class creates a new object. During that creation, Python automatically runs the object's __init__ method. The purpose of __init__ is to set up the object's initial attributes, giving the object its starting data. In the PartyAnimal example, creating an object sets its x attribute to 0.

PartyAnimalclass templatePartyAnimal()class call__init__automatic callx0callrunssets
What happens to an object's attributes when the object is created?
Code walkthrough
class PartyAnimal:
    def __init__(self):
        self.x = 0

    def party(self):
        self.x = self.x + 1
        print(self.x)

an = PartyAnimal()
  1. 1
    The class definition describes the data and behavior that PartyAnimal objects will have.
  2. 2
    When an = PartyAnimal() runs, Python creates an object and automatically calls __init__ on it.
  3. 3
    The assignment self.x = 0 gives that object its initial x value.
  4. 4
    The party method uses self.x to read and then increase the same object's value.
  • The class defines a PartyAnimal template.
  • The __init__ method sets the new object's x attribute to 0.
  • The party method changes the object's x attribute.
  • Calling PartyAnimal creates the object named an.

Following self Through a Method Call

The self parameter refers to the specific object on which a method was called. It lets the method access and modify that object's attributes. In the expression an.party(), self refers to an. Therefore, self.x means the x attribute belonging to an, rather than an attribute belonging to some other object.

anx = 0party()self = anself.xreads an.xx = 1an.xcallsuses selfupdates
How does self connect a method call to the specific object whose attributes the method reads or changes?

What do you think happens?

After an = PartyAnimal(), what will an.x be after three calls to an.party()?

  • 0

  • 1

  • 3

  • The class itself changes, but an.x does not

Reveal answer
Answer:

3

The object starts with x equal to 0. Each call to party uses self to increase that object's x by 1, so three calls produce x equal to 3.

Output
0
1
2
3

Designing Shared Behavior

Designing a class means deciding what data belongs to each object and what actions should operate on that data. The class holds the shared design for those attributes and methods. Each object created from the class has its own independent attribute data, while the methods provide reusable behavior for working with that data.

PartyAnimalentity typexattributeobjectsindividual instancespartymethoddefinesdefinesproduces
How are a real-world entity's shared data and behaviors translated into a class?
Best practice

Put behavior that operates on an object's own data into methods, and use self when those methods need to read or modify that data. This keeps one class definition reusable for as many objects as the problem requires.

Independent Object State

One class can produce many objects with the same structure but independent attribute data. If two objects are created from PartyAnimal, each begins with its own x value initialized by __init__. When a method uses self to change one object's x, it operates on the object connected to that method call.

PartyAnimalshared templateanx = 1anotherx = 0createscreates
How can one class produce multiple independent objects with the same structure but different attribute values?
python
Output
After the call, an.x is 1 and another.x remains 0.

Mistakes Beginners Make

  • Common mistake

    Treating the class definition as an object

    What it looks like

    Defining PartyAnimal and assuming an object already exists

    Why it fails

    The class keyword defines a template. It does not create an object.

    Do this instead

    Call the class, as in an = PartyAnimal(), to create an object.

  • Common mistake

    Ignoring the role of __init__

    What it looks like

    Expecting an object's initial x value without initialization

    Why it fails

    __init__ runs automatically when the object is created and sets up its initial attributes.

    Do this instead

    Use __init__ to establish the object's starting data.

  • Common mistake

    Using an object's data without self

    What it looks like

    Writing a method that changes x instead of using self.x

    Why it fails

    self identifies the particular object whose attribute the method should access or modify.

    Do this instead

    Use self.x when the method needs the object's x attribute.

  • Common mistake

    Assuming one object's method changes every object's data

    What it looks like
    Calling an.party() and expecting another.x to increase
    Why it fails

    self is bound to the object on which the method was called.

    Do this instead

    Track the object before the dot in the method call; an.party() operates on an.

Practice the Trace

EASY

Consider a PartyAnimal object that starts with x equal to 0. Trace the value of x after each of these calls: an.party(), an.party(), an.party(). Then explain which object self refers to during each call.

Hints
  • The object is initialized with x equal to 0.
  • Each party method call increases the selected object's x by 1.
  • In an.party(), self refers to an.
Worked example

Tracing Three Method Calls

Determine the value of an.x after an = PartyAnimal() followed by three calls to an.party().

  1. 1
    Create the object

    Calling PartyAnimal creates an object and automatically runs __init__, which sets an.x to 0.

  2. 2
    First call

    In an.party(), self refers to an. The method increases an.x from 0 to 1.

  3. 3
    Second call

    self still refers to an, so the method increases an.x from 1 to 2.

  4. 4
    Third call

    The same method changes the same object's attribute from 2 to 3.

Result

After three calls, an.x is 3.

Key Takeaways

  • A class is a template that defines the data and code its objects will have; it is not itself an object.
  • Calling a class creates an object, and __init__ runs automatically to initialize that object's attributes.
  • The self parameter refers to the specific object on which a method was called.
  • Methods use self to read and modify the correct object's attributes.
  • One class can create many objects with the same structure and independent data.

Related concepts

More concepts starting with D