Learning Objectives

  • Understand why a class would be used.
  • Be able to define a class.
  • Be able to define special functions, such as __init__.
  • Be able to create an object and access its members.
  • Distinguish between an instance of an object and an object definition.

References


What is a Class?

A class allows us to group certain functions with data. Generally, we consider related objects of a system. For example, an ATM machine allows for withdrawals and deposits. So, what sort of information do we want to contain? We need the total amount of money. So, we could design a class called ATM that has this relationship.

class ATM:
   def __init__(self, initial_money):
      self.money = initial_money
   def deposit(self, amount):
      self.money += amount
   def withdraw(self, amount):
      self.deposit(-amount)

atm = ATM(1000)
atm.deposit(30)
atm.withdraw(70)
print("We have {} dollars in the bank!".format(atm.money))

The code above produces the following output.

Don't worry about the syntax yet, the concepts are what I'm trying to get across here. Notice that we use an instance of an object called atm above. We create an instance of an object by using the class' name followed by the parameters that will go into the __init__ function. This function has a special meaning--namely, it's the function that is called when an object is created.

When we define a class, we use the keyword class. However, a class' definition doesn't have anything backing it. Instead, the definition is just a blueprint of what the class will look like in memory. To actually put memory to the blueprint, we create an instance of an object. The term instance here just means that the class is structured somewhere in memory.


Instances of an Object

An instance of an object is a class that is actually somewhere in memory. We don't know exactly where it is in memory, although we can find out. However, to make things easier, we use the self parameter to refer to that specific instance in memory from within the class itself. When we're using the object, we use the name of the variable we created separated by a '.' dot, which is called the member access operator.

The dot operator will look at your variable, which is just a convenient name for a location somewhere in memory. The dot operator will then grab whatever you requested from memory, be it a method--which is a function within an instance, or a field--which is a variable within an instance. Generally, we methods and fields are called members of a class.

If we forget the self when making a variable, we're creating a local variable that will not be accessible outside of the class. For example,

class MyClass:
   def __init__(self, value):
       myvalue = value

mc = MyClass(1000)
print("My value is {}".format(mc.myvalue))

The code above produces an error:

We get this because I set myvalue = value. However, we must always refer to fields using self.field. We can create many instances of a class, so we have to have some way to keep track of which class instance we're talking about. So, let's fix our code:

class MyClass:
   def __init__(self, value):
       self.myvalue = value


mc = MyClass(1000)
print("My value is {}".format(mc.myvalue))

Now that I added self.myvalue, we get the following:


Special Functions

There are several things we can do with a class, such as create it, print it, and delete it. Python will automatically call specific special functions when these types of events occur. The following link specifies the special functions available.

https://docs.python.org/3/reference/datamodel.html#basic-customization


Member Access

An instance of an object contains memory for all of the fields in the class. Now, we can refer to that memory location by the name of the variable we created. However, we also want to be able to access the data sitting in that memory location. We use the '.' dot operator, known as the member access operator.

https://docs.python.org/3/tutorial/classes.html#class-objects