Somebody asked Michael Williams if he could do Python and Java versions of his article An Introduction to Object-Oriented Programming in C++. 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?
I am assuming you know the basics of Python. If not, see the excellent Tutorial and the other documentation at http://www.python.org/doc/.
To represent Michael's house (in section Classy! in the C++ article), we can use the following code: (text version)
If we run it, it prints:#! /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"
My house is number 40 It has 8 rooms It has a garden
What does this program do? First, we define what a generic house is in the
class
block. pass
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 my_house
.
This house initially has no attributes--if we were to query
my_house.number
before setting it, we'd get an AttributeError.
The next three lines set and create 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.
We can initialize the instance at creation time by including a special
__init__
method. (A method is a function which "belongs" to a
class.) This program:
(text version)
prints:#! /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"
Because the class has anMy house is number 20 It has 1 rooms It does not have a garden
__init__
method, it's automatically
called when an instance is created. The arguments to House
are
really the arguments to __init__
. Although most programs don't,
you can also call __init__
yourself as many times as you want:
my_house.__init__(55, 14, 1)
. This tells the object to
"reinitialize itself".
Note that __init__
is defined with an extra first argument,
self
. But we don't specify
self
when we call the method. All Python methods work like
this.
self
is in fact the instance itself, and Python supplies it
behind the scenes. You need self
because it's the only way the
method can access the instance's attributes and other methods. Inside the
method,
self.rooms
means the instance's attribute rooms
, but
rooms
means the
local variable rooms
.
Local variables, of course, vanish when the method ends. Python's use of
self
is parallelled in Perl and other OO languages as well.
Michael didn't tell you, but C++ has a this
pointer which
works like Python's self
. However, in C++ you don't have to type
this->house
if there is no local variable house
,
and you never type this
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.
In fact, self
in Python is just a conventional name. You can
call it this
or me
instead if you like. I actually
like me
better. However, I stick with self
so that
if somebody else has to maintain my work later, it will be easier for them to
read. In contrast, C++'s variable this
is magic and cannot be
renamed.
In the C++ program, garden
is a boolean attribute. Python
doesn't have boolean attributes, so we use an integer instead. The expression
my_house.garden
is true if the attribute is 1 (or any
non-zero, non-empty value).
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 square.c
program would look like this:
(text version)
prints#! /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()
10
area
should be self explanatory because it works exactly like
__init__
above. To reiterate, all the self
s in
square.py are required. I have chosen to give Square an __init__
method rather than setting the attributes later, because that's what most
Python programmers would do.
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.
Not much to say here either. All Python attributes and methods are public. You can emulate private attributes and methods via the double-underscore hack, but most Python programmers don't. Instead, they count on the programmer not to abuse the class's API.
__init__
method is the constructor.
This prints:#! /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
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
Python has no equivalent to person alex[5]
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 for
loop (which sets
i
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 print
statement which access
an element by index number.