File: orr.html

package info (click to toggle)
lg-issue56 2-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,320 kB
  • ctags: 227
  • sloc: python: 72; makefile: 34; sh: 34
file content (306 lines) | stat: -rw-r--r-- 11,991 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>An Introduction to Object-Oriented Programming in Python LG #56</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->

<CENTER>
<A HREF="http://www.linuxgazette.com/">
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.jpg" 
	WIDTH="600" HEIGHT="124" border="0"></H1></A> 

<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue56/orr.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="skjoldebrand.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>

<!--endcut ============================================================-->

<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">An Introduction to Object-Oriented Programming in Python</font></H1>
<H4>By <a href="mailto:mso@mso.oz.net">Michael Orr</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




<P> Somebody asked Michael Williams if he could do Python and Java versions of
his article 
<A HREF="../issue55/williams.html">An Introduction to Object-Oriented
Programming in C++</A>.  Here's a Python version of the code.  I'll comment
on the differences between C++ and Python.  Perhaps somebody else can
write a Java version?

<P> I am assuming you know the basics of Python.  If not, see the 
excellent
<A HREF="http://www.python.org/doc/current/tut/tut.html">Tutorial</A>
and the other documentation at 
<A HREF="http://www.python.org/doc/">http://www.python.org/doc/</A>.

<H2>Houses and more houses</H2>

<P> To represent Michael's house (in section <STRONG>Classy!</STRONG> in the
C++ article), we can use the following code:
(<A HREF="misc/orr/house.py.txt">text version</A>)

<BLOCKQUOTE><PRE>
#! /usr/bin/python
"""house.py -- A house program.
This is a documentation string surrounded by triple quotes.
"""

class House:
	pass

my_house = House()
my_house.number = 40
my_house.rooms = 8
my_house.garden = 1

print "My house is number", my_house.number
print "It has", my_house.rooms, "rooms"
if my_house.garden:
	garden_text = "has"
else:
	garden_text = "does not have"
print "It", garden_text, "a garden"
</PRE></BLOCKQUOTE>

If we run it, it prints:

<BLOCKQUOTE><PRE>
My house is number 40
It has 8 rooms
It has a garden
</PRE></BLOCKQUOTE>

<P> What does this program do?  First, we define what a generic house is in the
<CODE>class</CODE> block.  <CODE>pass</CODE> means "do nothing" and is required
if the block would otherwise be empty.  Then we create an instance (that is, a
particular house) by calling the class name as if it were a function.  The
house is then stored in the variable <CODE>my_house</CODE>.

<P> This house initially has no attributes--if we were to query 
<CODE>my_house.number</CODE> before setting it, we'd get an AttributeError.
The next three lines set <EM>and create</EM> the attributes.  This is a
difference between the languages: Java instances start out with certain
attributes which can never change (although their values can change), but
Python instances start out with no attributes, and you can add or delete
attributes (or change their type) later.  This allows Python to be more flexible
in certain dynamic situations.

<P> We can initialize the instance at creation time by including a special
<CODE>__init__</CODE> method.  (A method is a function which "belongs" to a
class.)  This program:
(<A HREF="misc/orr/house2.py.txt">text version</A>)

<BLOCKQUOTE><PRE>
#! /usr/bin/python
"""house2.py -- Another house.
"""

class House:
	def __init__(self, number, rooms, garden):
		self.number = number
		self.rooms = rooms
		self.garden = garden

my_house = House(20, 1, 0)

print "My house is number", my_house.number
print "It has", my_house.rooms, "rooms"
if my_house.garden:
	garden_text = "has"
else:
	garden_text = "does not have"
print "It", garden_text, "a garden"
</PRE></BLOCKQUOTE>

prints:

<BLOCKQUOTE><PRE>
My house is number 20
It has 1 rooms
It does not have a garden
</PRE></BLOCKQUOTE>

Because the class has an <CODE>__init__</CODE> method, it's automatically
called when an instance is created.  The arguments to <CODE>House</CODE> are
really the arguments to <CODE>__init__</CODE>.  Although most programs don't,
you can also call <CODE>__init__</CODE> yourself as many times as you want:
<CODE>my_house.__init__(55,&nbsp;14,&nbsp;1)</CODE>.  This tells the object to
"reinitialize itself".

<P> Note that <CODE>__init__</CODE> is defined with an extra first argument,
<CODE>self</CODE>.  But we <EM>don't</EM> specify 
<CODE>self</CODE> when we call the method.  All Python methods work like
this.
<CODE>self</CODE> is in fact the instance itself, and Python supplies it
behind the scenes.  You need <CODE>self</CODE> because it's the only way the
method can access the instance's attributes and other methods.  Inside the
method, 
<CODE>self.rooms</CODE> means the instance's attribute <CODE>rooms</CODE>, but 
<CODE>rooms</CODE> means the 
<STRONG>local variable</STRONG> <CODE>rooms</CODE>.
Local variables, of course, vanish when the method ends.  Python's use of
<CODE>self</CODE> is parallelled in Perl and other OO languages as well.

<P> Michael didn't tell you, but C++ has a <CODE>this</CODE> pointer which
works like Python's <CODE>self</CODE>.  However, in C++ you don't have to type
<CODE>this-&gt;house</CODE> if there is no local variable <CODE>house</CODE>,
and you never type <CODE>this</CODE> on a method definition line.  In other
words, C++ (and Java) do the same thing as Python and Perl; they just hide it
from the programmer.

<P> In fact, <CODE>self</CODE> in Python is just a conventional name.  You can
call it <CODE>this</CODE> or <CODE>me</CODE> instead if you like.  I actually
like <CODE>me</CODE> better.  However, I stick with <CODE>self</CODE> so that
if somebody else has to maintain my work later, it will be easier for them to
read.  In contrast, C++'s variable <CODE>this</CODE> is magic and cannot be
renamed.

<P> In the C++ program, <CODE>garden</CODE> is a boolean attribute.  Python
doesn't have boolean attributes, so we use an integer instead.  The expression
<CODE>my_house.garden</CODE> is true if the attribute is 1 (or any
non-zero, non-empty value).

<H2>Don't be square</H2>

<P> This section corresponds to the "Member Functions" section in Williams'
article.  I prefer the term "method" over "member function", as Pythoneers
usually do.  Michael's <CODE>square.c</CODE> program would look like this:
(<A HREF="misc/orr/square.py.txt">text version</A>)

<BLOCKQUOTE><PRE>
#! /usr/bin/python
"""square.py -- Make some noise about a square.
"""

class Square:
	def __init__(self, length, width):
		self.length = length
		self.width = width

	def area(self):
		return self.length * self.width

my_square = Square(5, 2)
print my_square.area()
</PRE></BLOCKQUOTE>

prints

<BLOCKQUOTE><PRE>
10
</PRE></BLOCKQUOTE>

<P> <CODE>area</CODE> should be self explanatory because it works exactly like
<CODE>__init__</CODE> above.  To reiterate, all the <CODE>self</CODE>s in 
square.py are required.  I have chosen to give Square an <CODE>__init__</CODE>
method rather than setting the attributes later, because that's what most
Python programmers would do.

<H2>Function definitions outside the class definition</H2>

<P> Nothing to say here.  Python does not allow methods to be defined outside
the class.  Of course, this doesn't apply to ordinary (non-class) functions.

<H2>Public or private?</H2>

<P> Not much to say here either.  All Python attributes and methods are public.
You <EM>can</EM> emulate private attributes and methods via the 
<A HREF="http://www.python.org/doc/current/tut/node11.html#SECTION0011600000000000000000">double-underscore hack</A>, but most Python programmers don't.
Instead, they count on the programmer not to abuse the class's API.

<H2>Class constructors</H2>

The <CODE>__init__</CODE> method <EM>is</EM> the constructor.

<H2>Arrays and classes</H2>

Williams' array example can't be coded literally because of differences between
the languages, but one equivalent is:
(<A HREF="misc/orr/person.py.txt">text version</A>)

<BLOCKQUOTE><PRE>
#! /usr/bin/python
"""person.py -- A person example.
"""
class Person:
	def __init__(self, age, house_number):
		self.age = age
		self.house_number = house_number

alex = []
for i in range(5):
	obj = Person(i, i)
	alex.append(obj)

print "Alex[3] age is", alex[3].age
print

for alexsub in alex:
	print "Age is", alexsub.age
	print "House number is", alexsub.house_number
</PRE></BLOCKQUOTE>

This prints:
<BLOCKQUOTE><PRE>
Alex[3] age is 3

Age is 0
House number is 0
Age is 1
House number is 1
Age is 2
House number is 2
Age is 3
House number is 3
Age is 4
House number is 4                                                          
</PRE></BLOCKQUOTE>

<P> Python has no equivalent to <CODE>person&nbsp;alex[5]</CODE> in the C++
program, which creates an array of five empty instances all at once.  Instead,
we create an empty list and then use a <CODE>for</CODE> loop (which sets
<CODE>i</CODE> to 0, 1, 2, 3 and 4 respectively) to populate it.  The example
shows a loop subscripting a list by index number, another loop which gets each
element in the list directly, and a <CODE>print</CODE> statement which access
an element by index number.





<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P --> 
<H5 ALIGN=center>

Copyright &copy; 2000, Michael Orr<BR> 
Published in Issue 56 of <i>Linux Gazette</i>, August 2000</H5>
<!-- *** END copyright *** -->

<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue56/orr.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="skjoldebrand.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->