[Tutor] Classes and the like...
Erik Price
erikprice at mac.com
Sat Sep 20 11:48:29 EDT 2003
On Friday, September 19, 2003, at 09:56 PM, Intatia wrote:
> Object? What's an object? Didn't actually really know until just
> recently and
> it looks like it might take a bit for the whole idea to sink in and
> for me to
> use OO more.
A class is a definition of an object. Your original question asked
about classes, so I'm guessing people assumed that you were really
asking about objects.
You define an object by writing a class block, similar to how you
define a function by writing a function block. Think for a moment only
about functions:
1. You define a function once in your code.
2. Later, you can call that function in other places of your code.
Calling the function might produce a value (such as 3.14, or "Hello,
World!"), or it might just perform a side effect (such as storing data
into a database or writing text to a file). Or both.
The difference between a class definition and a function definition is
that whereas a function definition describes what should happen when a
function is called, a class definition describes the object that is
generated when the class's constructor is called. You call a
constructor to create an object. The constructor belongs to the class,
and in Python it looks an awful lot like a function. Think of the
constructor as a class-specific function, so if you create a "Book"
class and a "Magazine" class, you call the "Book" class constructor to
create Book objects and you call the "Magazine" class constructor to
create Magazine objects.
However, if writing a constructor was the only aspect of defining a
class, and a constructor is just a class-specific function, then why
not just write constructor functions and dispense with the whole hassle
of writing a class definition? The reason is because the constructor
is only one part of a class -- there can be other class-specific
functions, and even class-specific variables. In OO parlance, these
functions are often called "methods" and these variables are often
called "fields".
Here is an example of a simple Book class written in Python:
class Book:
def __init__(self):
self.title = ""
self.author = ""
self.publisher = ""
def getInformation(self):
info = "%s, by %s (%s)" % (self.title, self.author, self.publisher)
return info
The fact that we are dealing with a class is identified by the first
line, "class Book:". There are two methods of this class. You can
probably recognize that they look much like any other function, since
they start with the "def" keyword and are followed by parentheses and
an argument ("self" in this case). The first method is called
"__init__" and the second method is called "getInformation".
In Python (and only in Python), you create a constructor with a method
named "__init__". So as you can see, this class has a constructor.
The method accepts an argument ("self") and assigns an empty string to
three different attributes of the argument -- "self.title",
"self.author", and "self.publisher". In a class definition, the "self"
variable typically refers to the object that is to be created by this
class. So, knowing this, we can re-think our understanding of the
constructor -- it is assigning an empty string to the "title",
"author", and "publisher" attributes of the object that the constructor
is going to produce when it is invoked.
And a variable that is specific to a class is known as a "field" (just
like a function that is specific to a class is known as a "method").
Every object of a certain class contains the fields identified by the
class, so every Book object that we create will have "title", "author",
and "publisher" fields.
This sounds a bit confusing, so before going further why not try typing
in the above class into your interactive Python interpreter:
| wintermute:~$ python
|
| Python 2.2 (#1, 07/14/02, 23:25:09)
| [GCC Apple cpp-precomp 6.14] on darwin
| Type "help", "copyright", "credits" or "license" for more information.
| >>> class Book:
| ... def __init__(self):
| ... self.title = ""
| ... self.author = ""
| ... self.publisher = ""
| ... def getInformation(self):
| ... info = "%s, by %s (%s)" % (self.title, self.author,
| ... self.publisher)
| ... return info
| ...
| >>>
Now that we've defined a Book class, let's create an object from this
class:
| >>> book_1 = Book()
| >>>
We need some name by which to refer to our Book object, so I just used
the name "book_1". However, this choice is arbitrary, you can use any
legal Python variable name to refer to an object.
Now that we have a Book object, let's see what value is stored in its
"title" field. You can access an object's field by using the object's
name, followed by a period, followed by the name of the field. This is
sometimes called "dot notation":
| >>> book_1.title
| ''
| >>>
An empty string, just like we programmed our constructor to do. If you
try it with the "author" and "publisher" fields you will find the same
thing is true as well. So let's assign a name to our Book object by
using the traditional variable assignment:
| >>> book_1.title = "The Da Vinci Code"
| >>>
Now that we've assigned a title to the Book object, let's test it to
make sure that it actually got saved.
| >>> book_1.title
| 'The Da Vinci Code'
| >>>
Okay, let's continue to flesh out our object by storing values in its
other fields:
| >>> book_1.author = "Dan Brown"
| >>> book_1.publisher = "Doubleday"
| >>>
Now we have an object created by the constructor of the Book class, so
it is a Book object. We can refer to the three fields of our Book
object with dot notation. But there was another method of the Book
class that we defined -- "getInformation". You can access a method of
an object just like you access a field of an object, by using dot
notation. But methods, just like functions, are "called", so you need
to apply the parentheses at the end just like when you call a function
(this is how you indicate to Python that you are "calling" something).
So try it:
| >>> book_1.getInformation()
| 'The Da Vinci Code, by Dan Brown (Doubleday)'
| >>>
See what has happened? The "getInformation" method creates a string
containing the title, author, and publisher fields, and returns it.
This is how we programmed our "getInformation" method back when we
defined the class.
(Quick side note: you might be wondering why neither the constructor
nor the "getInformation" method were passed an argument, even though
the method definitions list an argument called "self". The reason for
this is actually pretty straightforward, but at this point not very
helpful to understanding how classes and object oriented programming
work, so simply take it at face value that class methods need the
"self" argument when they are defined (to refer to the object they are
invoked upon) but not when they are called.)
Of course, you can write any kind of method for a class, so that it
will be available to all objects of that class. And you can use
methods just like functions, so the following will work too:
| >>> message = "I am currently reading %s" % (book_1.getInformation())
| >>> message
| 'I am currently reading The Da Vinci Code, by Dan Brown (Doubleday)'
| >>>
One thing that makes OO programming so cool (there are actually many
things that make it cool IMHO) is that you can create as many instances
(objects) of a given class as you need. And, while all the instances
of the class share the same fields and methods, each can have its own
instance-specific data stored in those methods:
| >>> book_2 = Book()
| >>> book_2.title = "Text Processing in Python"
| >>> book_2.author = "David Mertz"
| >>> book_2.publisher = "Addison Wesley"
The information stored in book_2 is completely separate from the
information stored in book_1:
| >>> book_2.getInformation()
| 'Text Processing in Python, by David Mertz (Addison Wesley)'
| >>> book_1.getInformation()
| 'The Da Vinci Code, by Dan Brown (Doubleday)'
| >>>
Hope that makes some sense -- it should at least give you something to
go on as you explore classes and OO programming.
Erik
More information about the Tutor
mailing list