Instances of a Class¶
Thus far we have learned about the syntax for defining a new class of object, specifying its name, attributes, and methods [which are attributes that are functions]. Once we leave the scope of the class definition, a class object is formed - the resulting class object is the singular object that encapsulates our class definition. We seldom will want to pass around or manipulate this class object once it is created. Rather, we will want to use it to create individual instances of that class. To be more concrete, list is a class object [remember that class and type are synonymous] - it is the same sort of object that is produced when a class definition is executed. As you saw in Module 2, we can use this class object to create individual instances of the list class, each one containing its own sequence of items.
Each of these instances share the common attributes append, count, reverse, and so on, as specified in the definition of Pythons list class, which is encapsulated by the list class object. That being said, the specific content of any given list is an attribute of that particular list instance; that is, the content of a particular list is an instance attribute rather than a class attribute. Thus far, we do not have the ability to create instance-level attributes. Lets change that.
Suppose that we want to make our own Person class. Each person should have her/his own name, thus the name should be an instance-level attribute. We will learn to define a special initialization method that allows us to define and set instance-level attributes. In the context of Person, this will allow us to give each person their own name:
We will learn about the __init__ method and that peculiar self argument momentarily. First, we will learn about creating an instance object from a class object.
Object Identity and Creating an Instance¶
Here we will learn the basic mechanism for creating an instance of a class. Consider the following trivial class definition:
We can use the call syntax on Dummy, Dummy[], to create individual instances of this class:
Recall that the is operator checks to see if two items reference the exact same object in your computers memory. Also recall that the built-in isinstance function checks to see if an object is an instance of a class/type. These will help us understand the relationship between class objects, their instances, and references to objects.
See that Dummy is to d1 as list is to [1, 4, "a"]
Lets create another instance of Dummy. It is important to understand that this new instance is distinct from the one that we already created.
Pythons rules for referencing objects with variables still apply here: assigning an object to a variable, be it a class object or an instance, does not create a distinct copy of that object. The variable merely references that object, serving only as an alias for it.
Reading Comprehension: Class Initialization
Using the Dummy class defined above, create a list consisting of 10 distinct instances of this type. Write code to explicitly verify that each entry is distinct from the other, and that each entry is an instance of the Dummy class.
Then, create a tuple that contains a single instance of Dummy stored ten times. Write code to explicitly verify that the entries all reference the exact same object, and that each entry is an instance of the Dummy class.
Reading Comprehension: Terminology
Given:
What relationship do x and Cat share?
What relationship do y and Cat share?
What relationship do x and y share?
What relationship do x2 and y share?
What relationship do y and y1 share?
Next, identify each of the following objects as a class object or an instance [and if instance, an instance of what]
"hello world"
True
int
{"a" : 22}
tuple
Now that we know the basics of how to create an instance of a class, understand the relationship between class objects and instances, and understand the distinction between instances that are independent from one another, we can move on to learning about creating instance-level attributes for our class.
Defining Instance-Level Attributes: the __init__ Method¶
As demonstrated in the Person class that we defined earlier in this section, and the Rectangle class that we defined in this modules introduction section, there is a special method, __init__, that allows us to define instance-level attributes for our class. This is a critically-important method, which we will leverage often. Note that the name of this is: underscore-underscore-init-underscore-underscore, which can be pronounced as dunder-init [where dunder stands for double-underscore].
Consider the slightly-modified definition of Person, which also includes the class-attribute x:
Invoking Person[] actually calls __init__[] under the hood, and any argument that we feed to Person[] gets passed to __init__. Looking at our definition of __init__ it looks like we must pass two values to this method: self and name. This first argument, self, actually represents the object instance of Person that is being created. Python will pass the appropriate object for self to __init__ automatically, thus we need only worry about passing a value for name.
Lets make an instance of our Person class, passing the string "Kamasi" as the name:
Here is what is going on under the hood when we create this instance of Person [this is very important]:
Invoking Person["Kamasi"] first creates an instance of Person as if there was no __init__ method specified. The resulting object does not yet have a name attribute. It only has the class-level attribute x.
Next, that instance of Person is passed to __init__ as the argument self, and "Kamasi", which we provided explicitly, is passed as the argument name.
With these arguments, Person.__init__[self, "Kamasi"] executes its body of instructions. Specifically, self.name = name sets the attribute name on self, using the value "Kamasi".
Having finished executing the __init__ method, Person["Kamasi"] resolves by returning the instance-object that was created.
We now have the ability to define and set attributes on an instance-level! Understanding this process is critical to mastering object oriented programming in Python. Lets create several Person-instances, all stored in a list:
Updating the class-level attribute x of Person affects all instances of Person:
Reading Comprehension: Instance Attributes
Define a class, Tmp, that has three instance attributes: x, y, and z. x and y should be numbers that are set according to values passed to the instance creation, and z should be the product of these two values.
For example:
You should now have a grasp of how the special __init__ method can be used to define and set instance-level attributes for your classes. Furthermore, the basic process by which invoking class instantiation produces an instance object which then automatically gets passed to __init__ as the self argument, should be salient. In the following section, we will encounter three varieties of methods: instance methods, class methods, and static methods. Additionally, we will encounter even more so-called special methods, similar to __init__, which can be used to more broadly specify how your class behaves and interacts with Pythons operators.
Reading Comprehension Solutions¶
Solution: Class Initialization
Using the Dummy class defined above, create a list consisting of 10 distinct instances of this type
Write code to explicitly verify that each entry is distinct from the other, and that each entry is an instance of the Dummy class.
Create a tuple contains a single instance of Dummy ten times. Note here that we initialize Dummy once, and that the tuple-comprehension merely populates the tuple with that same instance ten times.
Write code to explicitly verify that the entries all reference the exact same object, and that each entry is an instance of the Dummy class.
Reading Comprehension: Terminology
Given:
What relationship do x and Cat share?: x and Cat reference the same class object.
What relationship do y and Cat share?: y is an instance of the Cat class.
What relationship do x and y share?: x references Cat, and y is an instance of Cat. Thus y is an instance of x.
What relationship do x2 and y share?: They are independent instances of Cat
What relationship do y and y1 share?: They reference the same instance of Cat.
Identify each of the following objects as a class object or an instance [and if so, an instance of what]
"hello world": An instance of the str type [a.k.a class]
True: an instance of the bool type
int: a class object describing integers
{"a" : 22}: an instance of the dict type
tuple: a class object describing tuples
Reading Comprehension: Instance Attributes
Define a class, Tmp, that has three instance attributes: x, y, and z. x and y should be numbers that are set according to values passed to the instance creation, and z should be the product of these two values.