Tutorial Details
- Program: Python
- Difficulty: Easy
- Estimated Completion Time: 25 minutes
Welcome back to lesson four in our Python from Scratch series. This tutorial will assume some prior knowledge of variables, data types, functions and print output. If you’re not up to date, check out the previous three articles in the series to catch up.
Today, we’re going to be delving into the subject of Object Oriented Programming (OOP). OOP is a very powerful way of organizing your code, and a solid understanding of the concepts behind it can really help you get the most out of your coding.
Prefer a Screencast?
Transcription
What is Object Oriented Programming?
Python is primarily designed as an object-oriented programming language – but what does ‘object oriented’ actually mean?
There are a variety of definitions for the term, and you could talk for literally hours trying to explain the complicated ins and outs, nuances and differences in implementations, but I’ll try to give a quick overview.
Broadly, object oriented programming is the concept that, in programming, the objects that we’re manipulating are more important than the logic needed to manipulate those objects. Traditionally, a program has been seen as a recipe – a set of instructions that you follow from start to finish in order to complete a task. That can still be true, and for many simple programs, that’s all which is required. That approach is sometimes known as procedural programming.
OOP puts objects at the center of the process.
On the other hand, as programs get more and more complex and convoluted, the logic needed to write them in a purely procedural way gets more and more twisted and hard to understand. Often object oriented approaches can help with that.
When we talk about object oriented approaches, what we do is put the objects at the center of the process, instead of simply using them as necessary containers for information as part of our procedural instructions. First, we define the objects we want to manipulate and how they relate to each other, and then we start to flesh it out with logic to make the program actually work.
When I talk about ‘objects’, I can be talking about all sorts of things. An ‘object’ can represent a person (as defined by properties such as name, age, address etc.), or a company (as defined by things like number of employees and so on), or even something much more abstract, like a button in a computer interface.
In this introduction, we’re not going to be covering all of the concepts in this topic because we’d be here all night, but by the end of the tutorial, I hope you’ll have a solid understanding of the principles you need to start straight away using some simple object-oriented techniques in your Python programs. Even better, these concepts are fairly similar in a lot of programming environments. The knowledge transfers over from language to language quite nicely.
Getting Started
I mentioned earlier that the first thing we should do when we’re going for an OOP approach is to define the objects we’re going to be using. The way we do this is to first define the properties that it possesses using a class. You can think of a class as a sort of template; a guide for the way an object should be structured. Each object belongs to a class and inherits the properties of that class, but acts individually to the other objects of that class.
An object is sometimes referred to as an ‘instance’ of a class.
As a simple example, you might have a class named ‘person’ with, say, an age and a name property, and an instance of that class (an object) would be a single person. That person might have a name of “Andy” and an age of 23, but you could simultaneously have another person belonging to the same class with the name of “Lucy” and an age of 18.
It’s hard to understand this without seeing it in practice, so let’s get some actual code going.
Defining a class
To define a class, in typical simple Python fashion, we use the word ‘class,’ followed by the name of your new class. I’m going to make a new class here, called ‘pet’. We use a colon after the name, and then anything contained within the class definition is indented. However, with a class, there are no parentheses:
class pet:
So now we’ve got a class, but it’s rather useless without anything in it. To start, let’s give it a couple of properties. To do this, you simply define some variables inside the class – I’m going to go with the number of legs to start with. As usual, you should always name your variables so that it’s easy to tell what they are. Let’s be original and call it ‘number_of_legs’. We need to define a value or we’ll get an error. I’ll use 0 here (it doesn’t matter too much in this case since the number of legs will be specific to each instance of the class – a fish doesn’t have the same amount of legs as a dog or a duck, etc. – so we’ll have to change that value for each object anyway).
class pet: number_of_legs = 0
Instances and member variables
A class on its own isn’t something you can directly manipulate; first, we have to create an instance of the class to play with. We can store that instance in a variable. Outside of the class (without any indentation), let’s make an instance of the class and store it in the variable, ‘doug’. To make a new instance of a class, you simply type the name of the class, and then a pair of parentheses. At this point, there’s no need to worry about the parentheses, but later on you’ll see that they’re there because, like a function, there’s a way of passing in a variable for use by the class when you first create the instance.
A class on its own isn’t something that you can directly manipulate.
class pet: number_of_legs = 0 doug = pet()
Now that we have an instance of a class, how do we access and manipulate its properties? To reference a property of an object, first we have to tell Python which object (or which instance of a class) we’re talking about, so we’re going to start with ‘doug’. Then, we’re going to write a period to indicate that we’re referencing something that’s contained within our doug instance. After the period, we add the name of our variable. If we’re accessing the number_of_legs
variable, it’s going to look like this:
doug.number_of_legs
We can treat that now exactly as we would treat any other variable – here I’m going to assume doug is a dog, and will give that variable the value of 4.
To access this variable, we’re going to use it again exactly as we would treat any other variable, but using that doug.number_of_legs
property instead of the normal variable name. Let’s put in a line to print out how many legs doug has so that we can show that it’s working as it should:
class pet: number_of_legs = 0 doug = pet() doug.number_of_legs = 4 print "Doug has %s legs." % doug.number_of_legs
If you run the code above, you’ll see that it’s printed out for us. It defined our ‘pet’ class, created a new instance of that class and stored it in the variable ‘doug’, and then, inside that instance, it’s assigned the value of 4 to the number_of_legs
variable that it inherited from its class.
So you can see from that very simplified example how you can begin to build nice, modular data structures that are clear and easy to use, and can start to scale quite nicely.
Introducing Logic
Okay, so that’s the very basics of classes and objects, but at the moment we can only really use classes as data structures – or, containers for variables. That’s all well and good, but if we want to start performing more complex tasks with the data we’re manipulating, we need a way of introducing some logic into these objects. The way we do that is with methods.
Methods, essentially, are functions contained within a class. You define one in exactly the same way as you would a function, but the difference is that you put it inside a class, and it belongs to that class. If you ever want to call that method, you have to reference an object of that class first, just like the variables we were looking at previously.
Methods, essentially, are functions contained within a class.
I’m going to write a quick example here into our pet class to demonstrate; let’s create a method, called ‘sleep’, which is going to print out a message when it’s first called. Just like a function, I’m going to put ‘def’ for ‘define’, and then I’m going to write the name of the method I want to create. Then we’re going to put our parentheses and semicolon, and then start a new line. As usual, anything included in this method is going to be indented an extra level.
Now, there is another difference between a method and a function: a method always, always, always has to have an argument, called ‘self’ between the parentheses. When Python calls a method, what it does is passes the current object to that method as the first argument. In other words, when we call doug.sleep()
, Python is actually going to pass the object ‘doug’ as an argument to the sleep method.
We’ll see why that is later, but for now you need to know that, with a method, you always have to include an argument called ‘self’ first in the list (if you want to add more arguments, you can add them afterwards, exactly like if you were passing multiple arguments to a function). If you don’t include that argument, when you run the code, you’re going to get an error thrown because Python is passing in an argument (this ‘self’ object), and the method is saying, ‘Hey, man, I don’t take any arguments, what are you talking about?’. It’s the same as if you tried to pass an argument into a function that doesn’t accept any arguments.
So here’s what we have so far:
class pet: number_of_legs = 0 def sleep(self): doug = pet()
Inside this method, we’re going to write a print statement like so:
class pet: number_of_legs = 0 def sleep(self): print "zzz" doug = pet()
Now, if we want to use this method, we simply use an instance of the pet class to reference it. Just like the number_of_legs
variable, we write the name of the instance (we’ve got one called doug), then a period, then the name of the method including parentheses. Note that we’re calling sleep using no arguments, but Python is going to add in that argument by itself, so we’re going to end up with the right amount of arguments in total.
class pet: number_of_legs = 0 def sleep(self): print "zzz" doug = pet() doug.sleep()
If you run this code, you should see that it prints out the message we wrote.
Data
Great, so now how about we write a new method to print out how many legs the pet has, to demonstrate how you can use methods to start manipulating the data within the class, and to demonstrate why we need to include this confusing ‘self’ argument. Let’s make a new method, called ‘count_legs
’.
This is where the ‘self’ argument comes in. Remember when we were accessing number_of_legs
from outside the class and we had to use ‘doug.number_of_legs’ instead of just ‘number_of_legs’? The same principle applies; if we want to know what is contained in that variable, we have to reference it by first specifying the instance containing that variable.
However, we don’t know what the instance is going to be called when we write the class, so we get around that using the ‘self’ variable. ‘self’ is just a reference to the object that is currently being manipulated. So to access a variable in the current class, you simply need to preface it with ‘self’ and then a period, like so:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs doug = pet() doug.number_of_legs = 4 doug.count_legs()
In practice, what this means is that wherever you write ‘self’ in your method, when you run the method that self is replaced by the name of the object, so when we call ‘doug.count_legs()’ the ‘self’ is replaced by ‘doug’. To demonstrate how this works with multiple instances, let’s add a second instance, representing another pet, called ‘nemo’:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs doug = pet() doug.number_of_legs = 4 doug.count_legs() nemo = pet() nemo.number_of_legs = 0 nemo.count_legs()
This will print out a message for 4 and then 0 legs, just as we wanted, because when we call ‘nemo.count_legs(),’ the ‘self’ is replaced by ‘nemo’ instead of ‘doug’.
In this way, our method will run exactly as intended because the ‘self’ reference will dynamically change depending on the context and allow us to manipulate the data only within the current object.
The main things you need to remember about methods is that they’re exactly like functions, except that the first argument has to be ‘self’ and that to reference an internal variable you have to preface the variable name with ‘self’.
Just as a note: You can actually use any name instead of ‘self’ for your methods. –The methods here would work just as well if we renamed the variable ‘self’ to any word. Using the name ‘self’ is simply a convention which is useful to Python programmers because it makes the code much more standard and easy to understand, even if it’s written by someone else. My advice would be to stick to the conventions.
Some More Advanced Features
Now that we’ve gone over the basics, let’s have a look at some more advanced features of classes, and how they can help make your programming easier to structure.
The next thing we’re going to talk about is inheritance. As its name might hint, inheritance is the process of making a new class based around a parent class, and allowing the new class to inherit the features of the parent class. The new class can take all of the methods and variables from the parent class (often called the ‘base’ class).
Inheritance is the process of making a new class based around a parent class.
Let’s extend our pet example to see how this might be useful. If we use ‘pet’ as our parent class, we could create a child class which inherited from the pet class. The child class might be something like ‘dog’, or ‘fish’ – something that is still a ‘pet’, but is more specific than that. A dog is a pet, and does the same things that all pets do – for example it eats and sleeps and has an age and a number of legs – but it does other things that are specific to being a dog, or at least more specific than to being a pet: dogs have fur, but not all pets do. A dog might bark, or fetch a stick, but not all pets would.
Getting back to the point, say we wanted to make a class in our program to represent a dog. We could use inheritance to inherit the methods and variables contained in ‘pets’ so that our dog could have a ‘numberOf Legs’ and the ability to ‘sleep’, in addition to all the dog specific things we might store or do.
Now, you might be wondering why we don’t put those methods and variables into the dog class and get rid of the pet class entirely? Well, inheritance gives us two distinct advantages over that approach: One, if we want an object that is a pet, but isn’t a dog – a generic pet, if you will – we can still do that. Two, perhaps later we want to add a second type of pet – maybe a fish. We can make that second class also inherit from pet, and so both classes can share everything in pet, but at the same time have their own more specific methods and variables that apply only to that type of object.
We’re getting a little bogged down in the theory here, so let’s write something to make it a little clearer. First, we’re going to write a new class, called ‘dog’, but this time, between the class name and the colon, we’re going to put some parentheses, and in them, we’re going to write the name of the class that we want to inherit from, sort of as if we’re passing this new class an argument, like we would a function.
Next, let’s give this class a simple method to demonstrate how it works. I’m going to add a ‘bark
’ method which will print ‘woof’:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs class dog(pet): def bark(self): print "Woof"
So, now let’s see what happens if we make an instance of this class. I’’m going to call our new dog ‘doug’ again. Now, if we call doug.bark()
:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs class dog(pet): def bark(self): print "Woof" doug = dog() doug.bark()
As expected, doug barks. That’s great, but we haven’t seen anything new yet – just a class with a method. What inheritance has done for us, though, is to make all of the pet functions and variables available to us through our ‘doug’ object, so if I do something like this:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs class dog(pet): def bark(self): print "Woof" doug = dog() doug.sleep()
Then the sleep method will also execute correctly. In effect, our doug object belongs to both the ‘pet’ AND the ‘dog’ class. To ensure that the variables do the same as the methods, let’s try this:
class pet: number_of_legs = 0 def sleep(self): print "zzz" def count_legs(self): print "I have %s legs" % self.number_of_legs class dog(pet): def bark(self): print "Woof" doug = dog() doug.number_of_legs = 4 doug.count_legs()
You can see that doug acts exactly as before, showing that our variables are being inherited. Our new child class is simply a specialized version of the parent one, with some extra functionality but retaining all of the previous functionality.
So there you have it, a quick introduction to object oriented programming. Stay tuned for the next installment in this series, where we’re going to be working with Python on the web!
Awh hell yeah! Been waiting for this fo’eva!
Thanks Giles! Can’t wait for the Django series. :)
+1
Cool stuff :-) Cant wait to get my read on.
Easy to understand tutorial, thanks. One thing that caught my eye was the usage of old sprintf style formatting in print statement:
print “I have %s legs” % self.number_of_legs
..where manual suggest usage like this:
print “I have {} legs”.format(self.number_of_legs)
Python 3 changed it from the old sprint method to the format method. It’s better, but a lot of things still don’t support Python 3. So it’s best to learn both methods thoroughly and test your framework or whatever out to see what it supports.
Btw, I think 2.7 supports .format() anyway, so format might be the way to go regardless (unless your host is old-dated or something).
I’m tired. :(
Awesome !
Thanks for the screencast.
It’s a good introduction to OOP and Python.
PLEASE NOTE: The YouTube and the iTunes versions of the cast do not have the proper times. It’s 20 minutes, yet YouTube and iTunes are 54 minutes. After the end of the cast, it is just silence and black screen for the remaining 33 minutes
+1 :(
No offense, but this series is proceeding at a snail’s pace…
His tuts are really verbose and expansive so they’ll not only serve newbies inside and out, but stand as a reference for future Python newbs.
If you’re itching to learn more Python, Lynda has Essential Training, and there’s always The Python Tutorial, amongst a million other resources.
Although I’m pretty anxious to learn some Django myself.
please
Make more python tutorials
You might have mentioned that methods in a class support chaining by returning the class itself. Also makes python look alittle like jquery.(see last line)
class pet:
number_of_legs = 0
def sleep(self):
print “zzz ”
return self
def set_Legs(self, legs):
self.number_of_legs = legs
return self
def count_legs(self):
print “I have %s legs” % self.number_of_legs
return self
class dog(pet):
def bark(self):
print “Woof”
doug = dog()
doug.set_Legs(4).count_legs().sleep().sleep().sleep()
Oh yeah, that’s a good point. I guess I didn’t want to add too much, to try and keep in simple for beginners, but this still would have been a nice thing to include in the lesson.
Thanks for the feedback!
This has been a great series and has been instrumental in my learning of Python. The tutorials and teaching have been thorough and complete. Thank you! Looking forward to the web edition!
Honestly,
this is the reason why nettuts is one of the first 5 sites I go to everytime I am online. keep it coming.
Thank you so much, great tut and explanation.
what would it be next , Django or web.py.
Can’t wait.
Nice tutorial, I have a few books that I’m learning Python from.
It’s a great, clean language but not especially suited to web development as other languages.
Anybody got any idea as to what types of programs I can try making to learn it better?
If you could make some real programs and put that up as a tutorial later on, I’d appreciate it.
I’d also love some Django tuts, felt it was a bit difficult to get up and running last time I messed with it.
Keep up the good work.
Real exercises: http://www.pythonchallenge.com/
Also, if anyone is itching for more screencasts MIT OpenCourse (yes… MIT will teach you Python in your living room) has everything online: http://www.youtube.com/watch?v=k6U-i4gXkLM
There is also Khan Academy (yes… Khan Academy) videos with exercises: http://www.khanacademy.org/#computer-science
There are also Django screencasts here: http://showmedo.com/videotutorials/django
One more thing, if anyone needs skill-oriented exercises, make them up yourself. Think of something very basic. Like… a dice roller. Make a 6 sided dice roller. Then add things onto it. Like, say some D&D nerd needs to roll several different types of dice. Let them pick what kind of die they need to roll, then roll it. Make it interactive and user-friendly to give you some practice working with strings.
Another example might be fetching some text off a certain website. Then seeing if you can get the text between an open and end tag. Then see if you can download and save that text, or if you can put it on your own website.
Basically, just think of something really simple and try to figure it out. Once you do that, then add on to it to make it better and better. That’s programming in a nutshell. The more you do this kinda stuff and struggle for answers, the better you’ll get. Read a book while you make up exercises and you’ll be sitting pretty.
This guy’s provided a lot of great links.
I also can’t recommend just making something enough.
Just pick something achievable and google every obstacle you come across until it’s finished.
We’re going to use Django in the final episode if that’s any help.
Great tutorial and I think you are progressing a the perfect pace for someone who is truly learning ‘from scratch’ !
Thanks for the great work, can’t wait to see the next one!
This article is awesome! Great explanation and well written!
Giles, thanks so much for the clear explanations. In my opinion, what set this series apart from other “Beginner’s Guides to Python”, is hearing someone take the time and explain things like what a function is and when we use it, what OOP is etc.
Hopefully more videos are on the way?!
Hey guys Im just asking politely could we have more python tutorials this series is just the BOMB! Thanks
This is amazing! Is there going to be a next lesson?
Very nice. I’m learning!
When are we going to have the final Lesson?
You’re the BEST teacher Out there!!!
Seriously! Thank You.
Thank you !
but where is the final lesson ?
I forgot what I learned already because I am not doing much with python too :(
Thank you very much. This tutorial really helped gel some of the OOP concepts that have been bouncing around in my head as I learn python. Much better understanding now. Thank you
Nice tutorial. But it would be nice if you could put out a simple Django tutorial as well. I just started working with Django from PHP, but can’t seem to get my head around it.
Hello,
I am trying to define a name function for my pet class, my code looks like this:
class pet:
name = ” ”
def my_name(self):
print “my name is %” %self.name
nemo = pet()
nemo.name = nemo
nemo.my_name()
but when I run my code i get the following error
file “pet_class.py” line 10, in nemo.my_name()
file “pet_class.py”, line 5, in my_name print “my name is %” %self.name
ValueError: incomplete format
how can i go about fixing this?
One more thing, instead of
nemo.name = nemo (->here you have substituted pet’s instance nemo under variable name)
write:
nemo.name = “nemo”
So, to sum up:
>>> class pet:
name = “”
def my_name(self):
print “my name is %s” %self.name
>>> nemo = pet()
>>> nemo.name = “nemo”
>>> nemo.my_name()
my name is nemo
Hi,
You are missing “%s”
This should be OK:
print “my name is %s” %self.name
@Morphik83
should be like this >> print “my name is %s ” % self.name
in my case “%” and “self.name” need a whitespace
:)
Sub say dash dash dash language hai yeh…..:’-((!!!
Fantastic tutorial. Really cleared up functions, classes, OOP in general. Thank you and keep ‘em coming! :)
Ns tut, first time i really understand classes. Ty, pls more tuts ur awesome^^
Thanks !
Was really helpful :)
Was worth reading!! Just teach in python 3+ from now on, since any one hardly uses it..
they should have made ‘self’ work like ‘this’(i.e shoudnt contain in the signature). Other than that I found this tutorial to be the best! Thanks alot.
To learn how to implement object oriented concepts in scenarios like developing a game, one can refer to the tutorial: https://www.youtube.com/watch?v=UBblRog4MGY