Classes & Objects - Python Made Easy (2013)

Python Made Easy (2013)

Chapter 6: Classes & Objects

“It always helps to be a good programmer. It is important to like computers and to be able to think of things people would want to do with their computers.”- Bill Budge

In this chapter you will learn about

· Classes

· Objects

· Inheritance

· Methods

· Attributes

Now that you have a basic understanding of functions, it's time to start putting it all together with classes. Classes expand upon the functionality provided by functions. They allow for greater flexibility, and can help to reduce lines of code in your program.

What Are Classes?

Classes are in a way very similar to functions. Unfortunately, there are some holes in the functionality of functions. They cannot store or save any information– like variables. Every time that a function is run, it starts anew– completely fresh. Classes are most often used when you need your function to actually effect the variables and parameters that you are sending it– rather than just spitting out a return value.

If you were creating a program that calculated and stored the value of all of your assets, you will need to change variables over time. Some of your assets will depreciate, requiring that the variables stored within functions are altered. What if you purchased additional assets that needed to be added to a list? Maybe you invested in new features (like an addition to a home) that requires that the assets value change over time. It's for situations like the ones we just mentioned that object-oriented-programming was created.

Classes are typically used after writing several functions that manipulate similar sets of data, or global variables. When several functions are altering the same data, it is best that they be grouped together as multiple different aspects of a single objec (a class, in this case).

A class is a blueprint. On it's own, it is not much of anything. Classes contain a number of statements that provide instructions. Variables can be altered within classes.

Defining and Creating Classes

Defining and creating classes is actually very similar to defining and creating functions. All you need to do is to specify that you are creating a class, by using the keyword ‘class’ and then, giving the class a class name. Here’s how classes are created:

class ClassName:

class_suite

ClassName.__doc__. will enable you to access the documentation string of a class. Functions, class members and various attributes are contained in the class_suite.

Here is the basic layout for creating a class;

# Defining a class

class class_name:

[statement 1]

[statement 2]

[statement 3]

[etc]

Now let's get a little bit more in depth. Here is a class that would be used in a basic banking program. This class instructs the program how to go about displaying the balance, depositing, withdrawing, and overdrawing accounts. It then prints the overall balance of the bank account after withdrawing 5 from it.

Class BankAccount(object):

def __init__(self, initial_balance=0):

self.balance = initial_balance

def deposit(self, amount):

self.balance += amount

def withdraw(self, amount):

self.balance -= amount

def overdrawn(self):

return self.balance < 0

my_account = BankAccount(15)

my_account.withdraw(5)

print my_account.balance

Notice how the class contains several different functions within it? The deposit, withdraw, and overdrawn functions all provide different instructions for the program, while altering variables, which would not be possible if this same program was laid out in several different functions. This allows several different functions to alter a variable that is local to the class that you have defined.

Class Terminology

There are a few different terms that you need to understand when using classes, related to object oriented programming.

· Class – A user-defined prototype for an object that defines a number of different attributes.

· Class variable – A variable that is present within a class, and is shared by all instances of that class. They are defined within the class, but not within the methods or functions that they class contains. Instance variables are used more than class variables.

· Data Member – A class variable that holds data associated with the class and its objects.

· Instance Variable – A variable that is defined inside of a method or function. It only exists within that function or variable.

· Method – A special function that is defined within a class.

· Object – A unique instance of data that is defined by the class.

Using Classes and Self

After creating classes, then you can use them throughout the entirety of your program. Classes can be called at any time throughout the program. You can also access attributes of the class from outside the instance, which allows you to use, alter, and manipulate variables used by the class from elsewhere within your program.

One of the main differences between methods and function is the parameter self.“Self” refers to the main object that is being altered by an operation. Using the self parameter is a catch-all for whatever is being altered within the class.

What Are Objects?

Ask any programmer about Python and he/she will tell you that it is an object-oriented program. Objects are data structures which consist of attributes, class variables, instance variables and other data of the sort. An object is always defined by its class.

When you create a single object within a class, you are creating an instance object. If you want to create an instance object you should 1) use the class name to invoke that class and 2) pass in an argument that 3) the __init__ argument should accept.

Let’s create a new class here and then, introduce new objects to it:

class Student:

stuCount = 0

def __init__(self, name, age):

self.name = name

self.age = age

Student.stuCount += 1

def displayCount(self):

print "Total Number of Students %d" % Student.stuCount

def displayStudent(self):

print "Name : ", self.name, ", Age: ", self.age

stuCount is a variable of the class, Student, in this example. You can access it from inside or outside of the class with Student.stuCount.
When creating new instances within a class, you need to initialize it first and this is done with the __init__ function. Python will use this function for initialization purposes. self is an argument that Python will add itself.


Now, let’s create instance objects:

stu1= Student (“Rob”,

24)

stu2= Student (“Alice”,

25)

Stu1 is the first instance of the class while stu2 is second instance of the same (Student) class.

Inheritance

One of the various advantages of object-oriented programming is that you need not make the same class all over again. This is a long and time-consuming process.

You can derive the same class from one that exists already. For this you need to insert the parent class in parentheses and this should be done right after the new class name.

When you do this the child class will inherit the attributes of the original/parent class and various data members and methods can be overridden by the child class. The syntax for inheritance is as follows:

class NameOfSubClass (ParentClassA[, ParentClassB, ….])

class_suite

Let’s consider the Student class for this:

class Student
def__init__(self, name, age):
self.name=name
self.age= age

This was the original class. Now, let’s use the same example to create a class entitled graduate which will take inherit from the parent class (student).

class Graduate (Student):

def __init__(self, name):
self.name= name
self.age= name

See, in this example Student was the parent class and graduate is the child class. I inserted the name of the parent class, right after that of the child class, in parentheses/brackets and the child class inherits the attributes of the parent class. __init__ was redefined for the child class, too.

It is also possible to inherit from several classes at the same time. Here’s the syntax for inheritance from multiple parent classes:

class 1:

….

class 2:

…..

class 3(1,2)
….

Define the two classes so the third class can then, inherit from both parent classes. Let’s consider the last two examples and make a third class (using the attributes of the Student and Graduate classes):

class Student (object)
def__init__(self):
super (Student, self) .__init__()

class Graduate (Student):

def __init__(self):
super (Graduate, self) .__init__()


class Masters (Graduate)

def__init__(self):
super (Masters, self) .__init__()

class GM (Graduate, Masters)
def__init__(self):
super(GM, self) .__init__()

How to Override Parent Class Methods


It is a good idea to override the methods of the parent class. This way you can change the functionality of the subclass. So, if you want to override the method of a class, this is how you should go about it:

class Student (object):
def __init__ (self):
pass

def message (self):

print “I have finally graduated!”

class Graduate (Student):

def__init__(self):

super (Graduate, self) .__init__()

def message (self):

print “I will now do my masters!”

super (Graduate, self). message ()

Instead of calling self.method, call the super(subclass, self).method. This way you can override self.method so the child class is now able to use super (Graduate.self) and it will produce the second (rather than the first) statement.

Accessing Attributes


If you want to access any object’s attributes, you need to use the dot operator for this purpose. So, let’s say you want to access the attributes of stu1 and stu2, here’s how you’ll do so:

stu1.displayStudent()
stu2.displayStudent()

print “Total Number of Students %d” % Student.stuCount

Put the entire code together and then, execute it. You will get the following:

Name: Rob, Age: 24
Name: Alice, Age: 25
Total Number of Students= 2

As was the case with dictionaries, you can use the del statement to get rid of or to modify an attribute of a class or that of an object.

Certain functions can be used to gain access to an attribute too. Here are examples of such functions:

delattr(obj, name) :this can be used to delete the attribute of an object.

Setattr(obj, name, value): if you want to introduce an attribute that does not exist, you can use this function to do so.
getattr(obj, name[, default]) : this is used to gain access to the attribute.

hasattr(obj,name):you can use this to see whether an object has attributes that can be modified. If it does not, you always use setattr to introduce an attribute.

Class Attributes

Python has in-built class attributes as well. One can access any of these attributes with the dot notation, just as you would access an object or class attribute.

__dict__- the class’ namespace is contained by this dictionary.

__name__: simply the class name
__doc__: the documentation string of the class. However, if there is none, this won’t show.
__module__: this is the name of the module in which the class has been defined.

__bases__: this can be an empty tuple.

Let’s use these class attributes for the aforementioned code:

class Student:

stuCount = 0

def __init__(self, name, age):

self.name = name

self.age = age

Student.stuCount += 1

def displayCount(self):

print "Total Number of Students %d" % Student.stuCount

def displayStudent(self):
print "Name : ", self.name, ", Age: ", self.age

print "Student.__doc__:", Student.__doc__

print "Student.__name__:", Student.__name__

print "Student.__module__:", Student.__module__

print "Student.__bases__:", Student.__bases__

print "Student.__dict__:", Student.__dict__

When you do so, you will get the following output:

Student.__doc__: Student base class for all employees

Student.__name__: Student

Student.__module__: __main__

Student.__bases__: ()

Student.__dict__: {'__module__': '__main__', 'displayCount': , 'stuCount': 0, 'displaystudent': , '__doc__': 'Common base class for all students, '__init__': }

What Happens to Unnecessary Objects?

Objects take up space but those objects that are no longer used or required are destroyed by Python. This is known as “garbage collection” because that is quite literally what the program does. This increases memory space and you can introduce more objects.

When the object’s reference count is at zero that is when Python knows to get rid of the object. Every time an object is given a new name its reference count will increase. On the other hand, every time you use the del statement or if the reference is reassigned, the reference count will decrease until it reaches 0 and is then, collected by the program.

This also happens in other programming languages (like C, C++ and Java, etc.) and you usually will not know or be notified of garbage collection because the program handles this on its own.

PROJECT: Classes

Now you are familiar with classes, so let's test your skills with a project. Try not to look at the answer until you have finished your own program. In this project we will be create a class that stores employ information. This class will contain 3 functions. The first function (__init__) will store the name, salary and total employee count. The second class, displayCount will display the total employee count, and the third class, displayEmployee, will display all of the recorded information on a given employee

Answer:

class Employee:

'Common base class for all employees'

empCount = 0

def __init__(self, name, salary):

self.name = name

self.salary = salary

Employee.empCount += 1

def displayCount(self):

print "Total Employee %d" % Employee.empCount

def displayEmployee(self):

print "Name : ", self.name, ", Salary: ", self.salary

Summary

ü This chapter’s focus was on:

· Classes

· Objects

· Inheritance

· Attributes

· How to access attributes

· The destruction of unnecessary objects