Getting started with Python (part 5 – for newbs)
Continuing from tutorial 4, we’ll discuss object oriented programming, classes, and how OO is applied in Python.
First of all, if we’re not doing object oriented programming, what kind of programming are we doing? Most likely, procedural. Procedural programming uses multiple functions to accomplish a task. Object oriented programming is the idea of packaging related variables and functions together in a reusable container called a class. Technically, OO is about modeling real world objects.
For example:
class Shower:
cold_waterrate = 0
hot_waterrate = 0
door_state = 0
def UpdateWaterRates(self):
API.SetColdRate(self.cold_waterrate)
API.SetHotWaterRate(self.hot_waterrate)
def UpdateDoorState(self):
API.SetDoorState(door_state)
The above code defines a class called Shower with data (cold_waterrate, hot_waterrate and door_state) and function members (UpdateWaterRates and UpdateDoorState).
Defining a class creates a blueprint. Basically, the instructions that are used to create an instance of the class.
You might be wondering what the self parameter is in the methods. self is a special word in Python that is automatically set to be the object that it was called on. Without a self parameter, we wouldn’t be able to access class data from inside our function. We’ll explore this again later.
In order to use our new class, we need to create an instance of the class. When an instance is created, the class definition is used to construct an object. So, what’s an object? Your monitor is an object, as is your mouse, keyboard and desk. Let’s take the mouse for example; It has blueprints or plans that are used to construct each mouse object, like the one on your desk.
Let’s create an instance of the Shower class:
shower1 = Shower()
On line 1, I call the Shower class (called the “The instantiation operation” (source)), which gives me a new instance of the Shower class, and I store that instance in shower1.
shower1 now contains a Shower object. I can access it like this:
# Like many languages, Python uses object.memberName # to access members of a class # Setting class data shower1.cold_waterrate = 15 shower1.hot_waterrate = 20 shower1.door_state = 0 # Calling class methods shower1.UpdateDoorState() shower1.UpdateWaterRates()
When I call shower1.UpdateDoorState, I don’t specify a value for the self parameter. It is automatically passed shower1. Technically, that’s not what really happens. The Python language converts the method call “shower1.UpdateDoorState()” to “Shower.UpdateDoorState(shower1)”.
Many classes have a special initial state that’s needed for them to work correctly. Python provides a special method that we can define called “__init__”.
Here’s what the shower class looks like with an “__init__” method:
class Shower:
cold_waterrate = 0
hot_waterrate = 0
door_state = 0
def __init__(self):
self.UpdateWaterRates()
self.UpdateDoorState()
def UpdateWaterRates(self):
API.SetColdRate(self.cold_waterrate)
API.SetHotWaterRate(self.hot_waterrate)
def UpdateDoorState(self):
API.SetDoorState(door_state)
Basically, this “__init__” method will make sure the water rates and door state are set to their defaults by calling the API methods when an instance is created.
Suppose we wanted to add parameters to the Shower() call? We can add them in the init method:
def __init__(self, cold_water, hot_water, door):
self.cold_waterrate = cold_water
self.hot_waterrate = hot_water
self.door_state = door
self.UpdateWaterRates()
self.UpdateDoorState()
Then, we’d create instances like this:
shower1 = Shower(15, 20, 0)
When you call “Shower(param1, param2, param2, etc)”, your parameters go to the init method. In the above case, init would have 15 in cold_water, 20 in hot_water and 0 in door.
Lots of things are objects
In Python, lots of different things are treated as objects. Class instances, functions, collections, etc.
Let’s look at an example function definition:
def Foo():
print "Foo."
In the function definition, we associate the name Foo with the function that we are defining. In Python, even though Foo is a function, it’s really an object, which can be very useful. Let’s say I want to have a function called when a task gets completed by another function. It’s easy to pass the function I want called to the worker function:
def Foo():
print "Foo."
def DoWork(callback):
print "Doing work..."
callback()
DoWork(Foo)
When DoWork calls it’s parameter callback, it will be calling Foo. We can also create additional names that point to the same function:
def Foo():
print "Foo."
Bar = Foo
# The below statements do the same thing
Foo()
Bar()
Most of the other things in Python that are treated as objects make sense, and I won’t cover them here.
Object copies
One thing to be really careful with is copying objects. Python does NOT do this for you.
If you were to do:
class Foo:
pass
temp1 = Foo()
temp1.something = 25
# This makes temp2 another name for the instance that
# temp1 points to
temp2 = temp1
# This will overwrite temp1.something
temp2.something = 50
If you wanted to copy the object temp1 into temp2:
temp2 = Foo() temp2.something = temp1.something
The same holds true for lists (since they’re objects too):
temp1 = ['item1', 'item2'] # This makes temp2 another name for the list that # temp1 points to temp2 = temp1 temp2[0] = 'itemmagic' # temp1[0] is now 'itemmagic'
Related topics
Something you might be wondering about:
class Foo:
pass
What was that “pass” statement? Literally, it means, do nothing. Execute will “pass” by the “pass” statement. The reason I used it was to create an empty container class, into which I could store data.
In the next tutorial, we’ll examine a real Python script.