Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
WEEK FOUR Object Oriented Python (Part 1) Congratulations on making it to Week 4, you’re now over half way! This week we’re going to make a start on learning about object oriented (OO) programming in Python. Next week, we’ll cover even more about OO in Python. At it’s core, object oriented programming is about storing data and the functionality for manipulating that data together in one place. What’s important is how that leads programmers to think about the problems they solve and design of their programs. 1 Some OO you already know In some sense, you’re already know a fair bit about object oriented programming (at least from a user’s perspective) because everything you’ve used already in Python is an object: strings, lists, dictionaries (and even functions) are objects that can be manipulated. You are already familiar with the main way of manipulating these objects: calling special functions (called methods) on them to change their data or properties, e.g.: >>> >>> >>> [1, x = [3, 1, 5, 7] x.sort() x 3, 5, 7] or calculate things based on these properties: >>> s = ‘‘hello world’’ >>> s.upper() ’HELLO WORLD’ Methods are special because they only apply to the type of object (the class, but we’ll come to this later) you are manipulating. For example, it doesn’t make sense to call the upper() method on a list or an integer. Method calls look different to function calls, with the object appears before the name of the method, to emphasise the importance of the object being manipulated. 2 Hiding the details Developments in programming languages have been driven by the goal of making programming easier, faster and more reliable. A key aspect of this is working out ways of minimising the vast number of details each programmer needs to consider and remember when programming. Functions are one of the best examples you’ve seen so far for hiding the details. All you need to know to use a function is: what the function needs as input (the arguments), what it returns, and any other side effects it has (e.g. writing to a file). It is possible to use a function without having any idea how it works. Object oriented programming gives an even greater opportunity to hide the details because it combines the data (the representation of the problem inside the program) with the algorithms that solve the problem (the code to manipulate the objects). c National Computer Science School 2005-2009 1 NCSS Challenge (Advanced) WEEK FOUR 3 A world without classes Let’s start with a problem: to represent circles in a program — lots of circles! Our circles are going to have two properties: colour and radius. We can already do this in several ways. We could create two lists, one of colours and one of radii: >>> colours = [’red’, ’green’, ’blue’] >>> radii = [3, 5, 10] but this is clumsy because we need to refer to each item using an index and we need to remember that the elements correspond between the colours and radii lists. For example, if we delete a colour we need to remember to delete the corresponding radius, otherwise our circles will get completely mixed up. We could use a list of tuples or lists: >>> circles = [(’red’, 3), (’green’, 5), (’blue’, 10)] >>> circles[1][0] ’green’ This is still messy because we’re now referring to the properties of our circles using indices. We need to remember that index 0 in the tuple is the colour, and index 1 is the radius. Also, we can’t modify the tuples, which is a pain. Finally, we could use a list of dictionaries: >>> circles = [{’colour’: ’red’, ’radius’: 3}, {’colour’: ’green’, ’radius’: 5}] >>> circles[1][’colour’] ’green’ This is actually quite close to the underlying storage of objects in Python, but the syntax is still a bit messy. Objects provide us with a much simpler syntax (any many other benefits we’ll come to later): >>> circles[1].colour ’green’ 4 A Circle class Let’s start with the (almost) simplest possible Circle class: class Circle: colour = ’red’ radius = 3 Notice that class is a keyword (similar to def in many ways). The name of the class comes next. The convention is that classes have title case names (capitalised first letter of each word, and lowercase for the rest of the word). Then we list all of the properties of the class (here the colour and the radius). In Python, the properties are called attributes. Note that the attributes are indented to indicate they are part of the class definition itself, and not a normal variable assignment. We can now construct a Circle object by calling the constructor: >>> c1 = Circle() >>> c1.colour ’red’ >>> c1.radius 3 c National Computer Science School 2005-2009 2 NCSS Challenge (Advanced) WEEK FOUR An object of a particular class is called an instance of the class. Here we’ve created our first instance of the Circle class. Calling the constructor involves what looks like a normal function call, with the name of the class instead, but there is a lot more going on under the bonnet as we will see later. We can change the values of each of the properties: >>> c1.colour = ’blue’ >>> c1.colour ’blue’ More importantly, if we create multiple Circle objects, each has its own colour and radius, which are stored independently. Changing one has on effect on the other: >>> c1 = Circle() >>> c2 = Circle() >>> c1.colour ’red’ >>> c2.colour ’red’ >>> c1.colour = ’green’ >>> c1.colour ’green’ >>> c2.colour ’red’ We can even use these in objects in lists, just like we wanted above: >>> circles = [c1, c2, c3] >>> circles[0].colour ’blue’ >>> circles[1].colour ’red’ 5 Adding methods to Circle Well, we’ve the properties for our Circle objects (the colour and the radius), but we promised you functionality too. So let’s add our first method, which calculates the area of the circle: import math class Circle: colour = ’red’ radius = 3 def area(self): return math.pi*self.radius**2 Before we explain how it works, let’s just see it in action. Calling area works just like to method calls on Python’s builtin in objects such as strings and lists: >>> c = Circle() >>> c.area() 28.274333882308138 Methods are functions defined as part of the class declaration. They are indented under class, just like the attributes to indicate they are part of the class. Methods always have at least one argument (the first argument) c National Computer Science School 2005-2009 3 NCSS Challenge (Advanced) WEEK FOUR which is always called self — this is the object that we are manipulating, the one which comes before the name when we call the method. Outside the object (e.g. at the interpreter prompt or your main program), the object is referred to using the name of the variable holding the object. In our example above, this is c. For example, c.radius returns the radius of the Circle object stored in the variable c. However, inside the object, the special name self is used to refer to the object we are manipulating. So inside the method call, when we call c.area(), self is now the Circle object in c, and we use self.radius to get the radius of the circle, which is needed to calculate the area. If we change the radius of the circle, and call area again, it will be updated for the new radius: >>> c.radius = 20 >>> c.area() 1256.6370614359173 Methods can also modify the attributes of an object. For example, if we add a set_radius method to our Circle: import math class Circle: colour = ’red’ radius = 3 def set_radius(self, r): self.radius = r def area(self): return math.pi*self.radius**2 we can now set the radius of the circle via the method rather than directly assigning to the attribute. We’ll see the importance of this later... >>> c.set_radius(5) >>> c.radius 5 6 The __init__ method The problem with our Circle class at the moment is that every object starts off with the same values for each attribute. What we need is a way of constructing circles with different properties. Python provides a special method called __init__ which gets called as part of the construction process to initialise the attributes of the object: import math class Circle: def __init__(self, colour, radius): self.colour = colour self.radius = radius def set_radius(self, r): self.radius = r def area(self): return math.pi*self.radius**2 c National Computer Science School 2005-2009 4 NCSS Challenge (Advanced) WEEK FOUR Now when we create circles, we need to specify both the colour and the radius values: >>> c1 = Circle(’red’, 3) >>> c2 = Circle(’blue’, 5) >>> c1.colour ’red’ >>> c2.colour ’blue’ Notice that the __init__ method, like area and set_radius has self as the first argument. Just like in set_radius, the self argument is used to set the attributes. Ok, we’re sure you’re itching to get onto the problems, so we’ll talk more about OO next week! If you want to play around with the circles example some more, you can find circles.py on the Challenge website. c National Computer Science School 2005-2009 5