author | Madhusudan.C.S <madhusudancs@gmail.com> |
Tue, 31 Aug 2010 20:14:18 +0530 | |
changeset 114 | 83b3e357ed08 |
parent 88 | 1e5c78018aa0 |
permissions | -rw-r--r-- |
53
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
1 |
Classes and Objects |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
2 |
=================== |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
3 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
4 |
In the previous sections we learnt about functions which provide certain level |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
5 |
of abstraction to our code by holding the code which performs one or more |
88
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
6 |
specific functionality. We were able to use this function as many times as we |
53
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
7 |
wanted. In addition to functions, Python also higher level of abstractions |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
8 |
through *Classes* and *Objects*. *Objects* can be loosely defined as a |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
9 |
collection of a set of data items and a set of methods. The data items can be |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
10 |
any valid Python variable or any Python object. Functions enclosed within a class |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
11 |
are called as *methods*. If you are thinking if methods are functions why is there |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
12 |
a distinction between the two? The answer to this will be given as we walk through |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
13 |
the concepts of *Classes* and *Objects*. *Classes* contain the definition for the |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
14 |
*Objects*. *Objects* are instances of *Classes*. |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
15 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
16 |
A class is defined using the keyword **class** followed by the class name, in |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
17 |
turn followed by a semicolon. The statements that a *Class* encloses are written |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
18 |
in a new block, i.e on the next indentation level:: |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
19 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
20 |
class Employee: |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
21 |
def setName(self, name): |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
22 |
self.name = name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
23 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
24 |
def getName(self): |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
25 |
return self.name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
26 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
27 |
In the above example, we defined a class with the name Employee. We also defined |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
28 |
two methods, setName and getName for this class. It is important to note the |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
29 |
differences between the normal Python functions and class methods defined above. |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
30 |
Each method of the class must take the same instance of the class(object) from |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
31 |
which it was called as the first argument. It is conventionally given the name, |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
32 |
*self*. Note that *self* is only a convention. You can use any other name, but |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
33 |
the first argument to the method will always be the same object of the class |
88
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
34 |
from which the method was called. The data members that belong to the class are |
53
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
35 |
called as *class attributes*. *Class attributes* are preceded by the object of |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
36 |
the class and a dot. In the above example, *name* is a class attribute since it |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
37 |
is preceded by the *self* object. *Class attributes* can be accessed from |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
38 |
anywhere within the class. |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
39 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
40 |
We can create objects of a class outside the class definition by using the same |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
41 |
syntax we use to call a function with no parameters. We can assign this object |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
42 |
to a variable:: |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
43 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
44 |
emp = Employee() |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
45 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
46 |
In the above example, we create an object named *emp* of the class *Employee*. |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
47 |
All the attributes and methods of the class can be accessed by the object of the |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
48 |
class using the standard notation *object.attribute* or *object.method()*. |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
49 |
Although the first parameter of a class method is the self object, it must not |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
50 |
be passed as an argument when calling the method. The *self* object is implicitly |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
51 |
passed to the method by the Python interpreter. All other arguments passing rules |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
52 |
like default arguments, keyword arguments, argument packing and unpacking follow |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
53 |
the same rules as those for ordinary Python functions:: |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
54 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
55 |
>>> emp.setName('John') |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
56 |
>>> name = emp.getName() |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
57 |
>>> print name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
58 |
John |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
59 |
>>> print emp.name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
60 |
John |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
61 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
62 |
If we at all try to access a class attribute before assigning a value to it, i.e |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
63 |
before creating it, Python raises the same error as it would raise for the |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
64 |
accessing undefined variable:: |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
65 |
|
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
66 |
>>> emp = Employee() |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
67 |
>>> emp.name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
68 |
Traceback (most recent call last): |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
69 |
File "class.py", line 10, in <module> |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
70 |
print e.name |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
71 |
AttributeError: Employee instance has no attribute 'name' |
76facb1dc81b
Added section for Classes and Objects.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
diff
changeset
|
72 |
|
88
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
73 |
It is also possible to assign values to the attributes using the above notation:: |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
74 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
75 |
>>> emp = Employee() |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
76 |
>>> emp.name = 'John' |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
77 |
>>> print emp.name |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
78 |
John |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
79 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
80 |
Magic methods |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
81 |
------------- |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
82 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
83 |
Python reserves a number of names starting and ending with **__**. Note that it |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
84 |
is a double underscore. We must not invent names of this kind in our programs. |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
85 |
These methods are generally referred to as *Magic methods* or sometimes called |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
86 |
as *Special Methods*. Each *Magic method* performs a specific function. One such |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
87 |
magic method we will discuss now is **__init__** method. If you are from C++ |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
88 |
background, the **__init__** method is analogous to the class constructor. This |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
89 |
method is called a constructor because, it is implicitly called everytime a new |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
90 |
instance of the class is created. So effectively **__init__** method constructs |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
91 |
the object from the class and sets up some initial values for the object. Other |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
92 |
than the above special properties, the **__init__** method is similar to any other |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
93 |
class method. The argument passing rules are same for **__init__** method. Although, |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
94 |
since **__init__** is called when the object is created we need to pass the |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
95 |
arguments to the class name we call while creating the object. It passes the |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
96 |
arguments to the **__init__** method:: |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
97 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
98 |
class Employee: |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
99 |
def __init__(self, name): |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
100 |
self.name = name |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
101 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
102 |
def getName(self): |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
103 |
return self.name |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
104 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
105 |
>>> emp = Employee('John') |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
106 |
>>> print emp.getName() |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
107 |
John |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
108 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
109 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
110 |
Writing Object Oriented Code |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
111 |
---------------------------- |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
112 |
|
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
113 |
Object oriented code mainly encompasses three components: Encapsulation, Inheritence and Polymorphism. |
1e5c78018aa0
Committing last changes.
Madhusudan.C.S <madhusudancs@gmail.com>
parents:
53
diff
changeset
|
114 |
Lets briefly look at each of them with examples. |