Sunday, May 19, 2013

Pthyon Classes


What is a class? Think of a class as a blueprint. It isn't something in itself, it simply describes how to make something. You can create lots of objects from that blueprint - known technically as an instance.

So how do you make these so-called 'classes'? Very easily, with the class operator:
Code Example 1 - defining a class
# Defining a class
class class_name:
    [statement 1]
    [statement 2]
    [statement 3]
    [etc.]
Makes little sense? Thats okay, here is an example that creates the definition of a Shape:
Code Example 2 - Example of a Class
#An example of a class
class Shape:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    description = "This shape has not been described yet"
    author = "Nobody has claimed to make this shape yet"
    def area(self):
        return self.x * self.y
    def perimeter(self):
        return 2 * self.x + 2 * self.y
    def describe(self,text):
        self.description = text
    def authorName(self,text):
        self.author = text
    def scaleSize(self,scale):
        self.x = self.x * scale
        self.y = self.y * scale
What you have created is a description of a shape (That is, the variables) and what operations you can do with the shape (That is, the fuctions). This is very important - you have not made an actual shape, simply the description of what a shape is. The shape has a width (x), a height (y), and an area and perimeter (area(self) and perimeter(self)). No code is run when you define a class - you are simply making functions and variables.
The function called __init__ is run when we create an instance of Shape - that is, when we create an actual shape, as opposed to the 'blueprint' we have here, __init__ is run. You will understand how this works later.
self is how we refer to things in the class from within itself. self is the first parameter in any function defined inside a class. Any function or variable created on the first level of indentation (that is, lines of code that start one TAB to the right of where we put class Shape is automatically put into self. To access these functions and variables elsewhere inside the class, their name must be preceeded with self and a full-stop (e.g. self.variable_name).

Using a Class [edit]

Its all well and good that we can make a class, but how do we use one? Here is an example, of what we call creating an instance of a class. Assume that the code example 2 has already been run:
Code Example 3 - Creating a class
rectangle = Shape(100, 45)
What has been done? It takes a little explaining...
The __init__ function really comes into play at this time. We create an instance of a class by first giving its name (in this case, Shape) and then, in brackets, the values to pass to the __init__ function. The init function runs (using the parameters you gave it in brackets) and then spits out an instance of that class, which in this case is assigned to the name rectangle.
Think of our class instance, rectangle, as a self-contained collection of variables and functions. In the same way that we used self to access functions and variables of the class instance from within itself, we use the name that we assigned to it now (rectangle) to access functions and variables of the class instance from outside of itself. Following on from the code we ran above, we would do this:
Code Example 4 - accessing attributes from outside an instance
#finding the area of your rectangle:
print rectangle.area()
 
#finding the perimeter of your rectangle:
print rectangle.perimeter()
 
#describing the rectangle
rectangle.describe("A wide rectangle, more than twice\
 as wide as it is tall")
 
#making the rectangle 50% smaller
rectangle.scaleSize(0.5)
 
#re-printing the new area of the rectangle
print rectangle.area()
As you see, where self would be used from within the class instance, its assigned name is used when outside the class. We do this to view and change the variables inside the class, and to access the functions that are there.
We aren't limited to a single instance of a class - we could have as many instances as we like. I could do this:
Code Example 5 - More than one instance
long_rectangle = Shape(120,10)
fat_rectangle = Shape(130,120)
Both long_rectangle and fat_rectangle have their own functions and variables contained inside them - they are totally independent of each other. There is no limit to the number of instances I could create.

Lingo 
Object-oriented programming has a set of lingo that is associated with it. Its about time that we have this all cleared up:

  • when we first describe a class, we are defining it (like with functions)
  • the ability to group similar functions and variables together is called encapsulation
  • the word 'class' can be used when describing the code where the class is defined (like how a function is defined), and it can also refer to an instance of that class - this can get confusing, so make sure you know in which form we are talking about classes
  • a variable inside a class is known as an Attribute
  • a function inside a class is known as a method
  • a class is in the same category of things as variables, lists, dictionaries, etc. That is, they are objects
  • a class is known as a 'data structure' - it holds data, and the methods to process that data.

Inheritance 

Lets have a look back at the introduction. We know how classes group together variables and functions, known as attributes and methods, so that both the data and the code to process it is in the same spot. We can create any number of instances of that class, so that we don't have to write new code for every new object we create. But what about adding extra features to our golf club design? This is where inheritance comes into play.

Python makes inheritance really easily. We define a new class, based on another, 'parent' class. Our new class brings everything over from the parent, and we can also add other things to it. If any new attributes or methods have the same name as an attribute or method in our parent class, it is used instead of the parent one. Remember the Shape class?
Code Example 6 - the Shape class
class Shape:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    description = "This shape has not been described yet"
    author = "Nobody has claimed to make this shape yet"
    def area(self):
        return self.x * self.y
    def perimeter(self):
        return 2 * self.x + 2 * self.y
    def describe(self,text):
        self.description = text
    def authorName(self,text):
        self.author = text
    def scaleSize(self,scale):
        self.x = self.x * scale
        self.y = self.y * scale
If we wanted to define a new class, let's say a square, based on our previous Shape class, we would do this:
Code Example 7 - Using inheritance
class Square(Shape):
    def __init__(self,x):
        self.x = x
        self.y = x
It is just like normally defining a class, but this time we put in brackets after the name, the parent class that we inherited from. As you see, we described a square really quickly because of this. That's because we inherited everything from the shape class, and changed only what needed to be changed. In this case we redefined the __init__ function of Shape so that the X and Y values are the same.
Let's take from what we have learnt, and create another new class, this time inherited from Square. It will be two squares, one immediately left of the other:
Code Example 8 - DoubleSquare class
# The shape looks like this:
# _________
#|    |    |
#|    |    |
#|____|____|
 
class DoubleSquare(Square):
    def __init__(self,y):
        self.x = 2 * y
        self.y = y
    def perimeter(self):
        return 2 * self.x + 3 * self.y

No comments:

Post a Comment