Concepts / Accessing Object Attributes and Methods

Accessing Object Attributes and Methods

The real power of object-oriented programming is creating multiple instances of a class, each with its own independent data.

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

One Class, Many Objects

A class can serve as a template for creating many distinct objects. The important step beyond creating one object is creating several instances that belong to the same class but hold different data. For example, two PartyAnimal objects can begin with different names. They share the class definition, but each object has its own state.

Following Constructor Data

A constructor receives self and any additional parameters supplied by the caller. The self parameter refers to the object instance being created. An additional parameter carries a value chosen for that particular object. Inside the constructor, an assignment such as self.name = nam copies the parameter value into the name attribute of the object represented by self.

'Sally'constructor argumentnamconstructor parameterself.nameattribute assignmentPartyAnimalname = 'Sally'passed toused bystores in
How does a value passed when constructing an object become stored in that object's instance attribute?

The flow is specific to the object being created: the caller supplies a value, the constructor receives it through its parameter, and self.attribute stores it on that object. The assignment does not describe a single shared name for every instance; it stores the value in the current object's attribute.

Constructing Distinct Instances

python

The first construction passes 'Sally' to the constructor. During that construction, self refers to the new object assigned to s, so that object's x becomes 0 and its name becomes 'Sally'. The second construction creates a completely new object assigned to j. Its x also begins at 0, but its name becomes 'Jim'.

ObjectInitial x attributeInitial name attribute
s0'Sally'
j0'Jim'

The same class creates two objects with different initial name values.

PartyAnimalclass templatesx = 0; name = 'Sally'jx = 0; name = 'Jim'createscreates
How can two objects created from the same class contain different values for the same attribute without changing each other?

Reading and Changing One Object

An expression such as s.name accesses the name attribute belonging to the object referenced by s. Likewise, j.name accesses the name attribute belonging to the object referenced by j. Because each object maintains independent copies of its attributes, accessing or changing one object's data does not change the other object's corresponding data.

Code walkthrough
class PartyAnimal:
    def __init__(self, nam):
        self.x = 0
        self.name = nam

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

s = PartyAnimal('Sally')
j = PartyAnimal('Jim')
s.party()
  1. 1
    PartyAnimal('Sally') creates the object referenced by s and initializes its x to 0 and name to 'Sally'.
  2. 2
    PartyAnimal('Jim') creates a separate object referenced by j and initializes its x to 0 and name to 'Jim'.
  3. 3
    s.party() calls the method for the object referenced by s.
  4. 4
    Inside the method, self refers to s, so self.x is that object's x attribute.
  5. 5
    The increment changes s.x to 1 while j.x remains 0.
  • The constructor gives s its own x and name attributes.
  • The second construction gives j its own x and name attributes.
  • The call s.party() operates on the object represented by s.
  • That object's x changes from 0 to 1; j's x remains 0.
s.party()method callselfthe object ss.x0s.x1selectsreadsincrements
How does a method call know which object's attributes to read or modify?

Tracing the Complete Setup

Worked example

Two Names, Two Object States

Trace the values stored after constructing s = PartyAnimal('Sally') and j = PartyAnimal('Jim'). Then trace the effect of calling s.party().

  1. 1
    Create s

    The constructor receives 'Sally'. For the new object referenced by s, self.x is set to 0 and self.name is set to 'Sally'.

  2. 2
    Create j

    The constructor runs again for a new object. This object's x is set to 0 and its name is set to 'Jim'.

  3. 3
    Call s.party()

    The method uses self to refer to s. It increments s.x from 0 to 1.

  4. 4
    Compare the objects

    The objects still hold independent data: s has x equal to 1 and name equal to 'Sally'; j has x equal to 0 and name equal to 'Jim'.

Result

Changing the x attribute through s.party() changes s but does not change j.

What do you think happens?

After s = PartyAnimal('Sally'), j = PartyAnimal('Jim'), and s.party(), what are the x values for s and j?

  • s.x is 1 and j.x is 0

  • s.x is 1 and j.x is 1

  • s.x is 0 and j.x is 1

Reveal answer
Answer:

s.x is 1 and j.x is 0

Each object has its own independent x attribute. The method call through s increments only s's x.

Mistakes with Instance Data

  • Common mistake

    Treating a constructor parameter as if it automatically became an attribute.

    What it looks like

    The constructor receives nam, but the object has no stored name unless the constructor assigns self.name = nam.

    Why it fails

    A parameter is used inside the constructor, while self.name is the attribute that stores the value on the object.

    Do this instead

    Copy the parameter into an instance attribute with an assignment such as self.name = nam.

  • Common mistake

    Assuming that objects made from the same class share the same attribute values.

    What it looks like

    Assuming that changing s.x also changes j.x.

    Why it fails

    Each object maintains its own independent copies of attributes.

    Do this instead

    Track the object named before the dot. s.x and j.x belong to different instances.

  • Common mistake

    Thinking that a method call operates on every instance of the class.

    What it looks like

    Assuming s.party() increments both Sally's and Jim's x values.

    Why it fails

    The call is made through s, so the method uses self for the object represented by s.

    Do this instead

    Identify the instance used for the call and follow that instance's attributes.

Practice the Data Flow

MEDIUM

Suppose a class constructor receives a parameter called nam and contains self.name = nam. Two objects are created with different name arguments. Explain, in order, how each argument reaches the correct object's name attribute. Then explain why changing an attribute through one object does not change the corresponding attribute in the other object.

Hints
  • Start with the value supplied in each constructor call.
  • Identify which object self refers to during each constructor execution.
  • Separate the attributes belonging to the two object instances.

Key Takeaways

  1. 1
    A class can be used as a template for creating multiple distinct objects.
  2. 2
    Constructor parameters beyond self let each object receive unique initial values.
  3. 3
    An assignment such as self.name = nam stores a constructor parameter in the current object's attribute.
  4. 4
    Each object maintains independent copies of its attributes.
  5. 5
    A method call made through one object reads or changes that object's attributes rather than the attributes of every instance.

At a glance

  • A single class definition can create many objects with different data.
  • Constructor arguments flow through parameters and into instance attributes using assignments such as self.attribute = parameter.
  • Each object has independent copies of its attributes.
  • Accessing or changing one object's attributes does not affect another object's attributes.
  • A method call through a particular instance operates on that instance's state.

Related concepts

More concepts starting with A