How programs with objects execute

First, let’s finish our class from last time:

class DJData:
    def __init__(self, default: str):
        self.queue = []
        self.num_callers = 0
        self.default_song = default

    def request(self, caller: str, song: str) -> str:
        self.queue.append(song)
        self.num_callers += 1
        if self.num_callers % 1000 == 0:
            return "Congrats, " + caller + "! You get a prize!"
        else:
            return "Cool, " + caller

    def play(self) -> str:
        if len(self.queue) == 0:
            return self.default_song
        song = self.queue[0]
        del self.queue[0]
        return song

We can interact with DJData objects using these methods:

> djd = DJData("Wonderwall")
> djd.play()
"Wonderwall"
> djd.request("Doug", "Ironic")
> djd.request("Jessica", "Smells Like Teen Spirit")
> djd.play()

Notice that in order to use our DJData class, we don’t need to know anything about how it’s implemented: we don’t need to know what the bodies of its methods look like, and we don’t even need to know what fields it has. This is the power of objects: they let us consider pieces of code and data in isolation!

Objects in memory

Objects live in the program memory in the same way that lists, hashtables, and sets do. When we execute a method, Python looks up the object’s class in order to determine which function to call. It makes sure that the first argument to the method (usually called self) points at the right object. See the lecture capture for details!