Concepts / Understanding self and Instance Attributes

Understanding self and Instance Attributes

When you create an instance from a custom class, that instance is an object of the custom type. It is not automatically an int or a str, even if one of its attributes contains an integer or a string.

  • 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…

A New Category of Object

Python's class keyword does more than organize related code. It creates a new type. Python already provides built-in types such as int and str, but a class lets you introduce another category of object that Python recognizes as its own type.

Key point

When you create an instance from a custom class, that instance is an object of the custom type. It is not automatically an int or a str, even if one of its attributes contains an integer or a string.

PartyAnimalcustom typeaninstancexinteger attributean2instancexinteger attributecreates instancescreates instanceshashas
What does a class definition create, and how are the custom type, its instances, and their attributes related?

Following self to an Instance

An instance attribute is data associated with one particular object. In the PartyAnimal example described in the source, each instance has an x attribute, and the party method increments that instance's x value. The name self identifies the particular instance involved when the method works with that attribute. Therefore, a method call on an points to an's x, while a method call on a second instance points to that second instance's x.

an.party()method callselfanxan's attributean2.party()method callselfan2xan2's attributeselectsusesselectsuses
How does self connect a method call to the particular instance whose attributes are read or changed?
Code walkthrough
class PartyAnimal:
    def __init__(self):
        self.x = 0

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

an = PartyAnimal()
an2 = PartyAnimal()
an.party()
an2.party()
  1. 1
    The class definition introduces PartyAnimal as a custom type.
  2. 2
    The __init__ method gives each new instance an x attribute.
  3. 3
    The party method changes the x attribute belonging to the selected instance.
  4. 4
    an and an2 are separate objects, so changing one instance's x does not change the other instance's x.
  • The class statement creates the PartyAnimal type.
  • Each PartyAnimal instance receives its own x attribute.
  • self.x refers to the x belonging to the instance whose party method is called.
  • The two instances begin with separate x attributes, so each call produces the value 1.
Output
party 1
party 1

Reading an Object's Type

The type() function reports the class of an object. For a built-in value such as 5, type() identifies int. For a string such as 'Alice', it identifies str. For the instance an created from PartyAnimal, it identifies PartyAnimal. This confirms that the class is a real type recognized by Python.

python
Output
<class 'int'>
<class 'str'>
<class '__main__.PartyAnimal'>
<class 'int'>
Key point

The type of an object and the types of its attributes are separate questions. In this example, an has type PartyAnimal, while an.x has type int.

5type intan.xtype intAlicetype strantype PartyAnimalhas
How is an instance of a custom class different from an int or str object, even though all are Python objects?

Inspecting Attributes with dir

The dir() function lists the attributes and methods available on an object. For a PartyAnimal instance, the listing includes the user-defined x attribute and party method. It also includes special methods that Python automatically provides to every class. The complete listing can be long, so the important skill is to use dir() as an inspection tool: look for the names your class defines, while remembering that the object also has Python-provided members.

python
Output
True
True
anobjectxinstance attributedir(an)names availablepartymethodspecial methodsPython-provided membersinspect withlistedlistedlisted
Which attributes and methods does dir(instance) reveal, and which come from the instance versus its class?

Mistakes Beginners Make

  • Common mistake

    Treating a class as only a container for code

    What it looks like

    Thinking of PartyAnimal as a folder that merely stores __init__ and party

    Why it fails

    The class keyword creates a new type, and instances created from it are objects of that type.

    Do this instead

    Use type(an) to confirm that the instance has type PartyAnimal.

  • Common mistake

    Assuming an instance has the type of one of its attributes

    What it looks like

    Assuming an has type int because an.x is an integer

    Why it fails

    The instance and its attribute are different objects and can have different types.

    Do this instead

    Check them separately with type(an) and type(an.x).

  • Common mistake

    Assuming two instances share the same instance data

    What it looks like

    Expecting an2.x to change when an.x changes

    Why it fails

    Separate instances have separate data. The source describes each PartyAnimal instance as having its own x attribute.

    Do this instead

    Track the selected instance through self when a method reads or changes x.

  • Common mistake

    Expecting dir() to show only names written by the programmer

    What it looks like

    Being confused when special methods appear in dir(an)

    Why it fails

    dir() lists user-defined attributes and methods as well as special methods Python automatically provides.

    Do this instead

    Use dir() as a complete inventory of available names, not as a copy of only your class body.

Practice the Inspection Tools

Worked example

Class, Instance, and Attribute

A PartyAnimal instance is stored in an. What should you expect from type(an), type(an.x), and dir(an)?

  1. 1
    Identify the instance type

    Because PartyAnimal is a class and an is created from it, type(an) reports PartyAnimal.

  2. 2
    Identify the attribute type

    The x attribute is initialized as an integer, so type(an.x) reports int.

  3. 3
    Inspect available names

    dir(an) includes x and party, along with special methods supplied by Python.

Result

The instance has type PartyAnimal, its x attribute has type int, and dir(an) reveals the names available through the instance.

EASY

Suppose you create two PartyAnimal instances named first and second. Explain why both can have type PartyAnimal while still having separate x attributes. Then describe what dir(first) should help you find.

Hints
  • Separate the question about the class of an object from the question about the data stored on that object.
  • Remember that each instance has its own x attribute.
  • Look for both the user-defined names and the special methods in dir(first).

The Working Mental Model

  1. 1
    The class keyword creates a new custom type, not merely a container for code.
  2. 2
    An instance created from a class is an object of that class's type, just as 5 is an object of type int.
  3. 3
    self identifies the particular instance whose attributes a method reads or changes.
  4. 4
    type(object) reports the object's class, while type(object.attribute) reports the attribute's class.
  5. 5
    dir(object) lists available attributes and methods, including user-defined names and Python-provided special methods.

Key Takeaways

  • A Python class defines a new type that Python can recognize.
  • Instances of the same class share the class type but remain separate objects with separate instance data.
  • self connects a method's attribute operations to the particular instance involved in the method call.
  • Use type() to identify an object's class and dir() to inspect its available attributes and methods.
  • A custom instance can have one type while its attributes have other types.

Related concepts

More concepts starting with U