Objects in Python

In Python, everything is an object — numbers, strings, lists, dictionaries, even functions. You might not always see it because Python hides most of the technical details behind its simple syntax.

For example:

score = 10

Here’s what actually happens:

You don’t normally need to worry about how Python builds objects unless you want to:

What exactly is an object?

An object is a container that can hold:

You can think of:

For example:

Every object is created from a class, which acts as a blueprint.

Objects are everywhere

Examples of built-in Python objects:

Multiple objects, different values

Unlike modules (which are single files), you can have many objects of the same type at the same time, each with its own attributes.

For example, you can have two different book objects:

class Book:
    pass

book1 = Book()
book2 = Book()

This is the smallest possible class: it does nothing yet. The pass statement means “do nothing” and is only there so Python accepts the empty class.

If you print an object without a custom display method, Python shows its type and a memory address:

class Dog:
    pass

buddy = Dog()
rocky = Dog()

print(buddy)  # <__main__.Dog object at 0x7f21a8b2fa90>
print(rocky)  # <__main__.Dog object at 0x7f21a8b2fcd0>

These memory addresses change every time you run the code.

Adding attributes to objects

You can add attributes to objects after creating them:

buddy.name = "Buddy"
buddy.age = 4

Objects can also refer to other objects as attributes:

buddy.friend = rocky

If you try to access an attribute that doesn’t exist, Python raises an AttributeError:

print(buddy.friend.name)
# AttributeError: 'Dog' object has no attribute 'name'

We can fix this by giving the friend object a name:

buddy.friend.name = "Rocky"
print(buddy.friend.name)  # Rocky

When programmers talk about “attributes,” they usually mean object attributes. There are also class attributes, which we’ll discuss later.

Setting attributes at creation time

If you want an object to have attributes right from the start, use Python’s initializer method __init__():

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

The self argument specifies that it refers to the individual object itself. When you define __init__() in a class definition, its first parameter should be named self . Although self is not a reserved word in Python, it’s common usage.

Now we can pass values when creating a new object:

puppy = Dog("Max", 2)
print(puppy.name)  # Max
print(puppy.age)   # 2

How it works step-by-step

When you write:

puppy = Dog("Max", 2)

Python:

This new object is like any other object in Python. You can use it as an element of a list, tuple, dictionary, or set. You can pass it to a function as an argument, or return it as a result.

You don’t have to put an __init__() method in every class. We use it only when we want to give an object special settings or values that make it different from other objects of the same class. In some programming languages, this is called a “constructor,” but in Python the object is already created before __init__() runs. You can think of __init__() as a setup step that prepares the new object.

Why use objects?

Objects make your code:

Instead of:

names = ["Buddy", "Rocky"]
ages = [4, 6]

You can do:

dogs = [
    Dog("Buddy", 4),
    Dog("Rocky", 6)
]

Now each dog has both its name and age stored together.

Recap