Section 3: Classes & Objects
Table of Contents >
Chapter 5 > Section 3
The opening documentation for the random
module referred to
the Random
class. The term class and the
associated term object are used extensively in the documentation of
Python modules. In this section of the course we examine what these
terms mean.
A class encapsulates data along with associated operations on that data. You
can think of a class as a blueprint for a new type of data. We use the
blueprint to create instances of that data. These instances are known
as objects.
It so happens that we've been using classes and objects throughout the
course without mentioning them explicitly. In fact, every piece of
data that we have worked with is an object and is therefore an
instance of some class. We have noted that a class
encapsulates data and associated operations on that data. These
operations are known as methods. The str
data
type, for example, is defined by a class. The methods for this class
are documented in Section
4.7.1 of the Standard Python Library. Let's take a look at the
documentation for the center method, for example:
str.center(width[, fillchar])
Return centered in a string of length width. Padding is done using
the specified fillchar (default is a space).
(http://docs.python.org/3/library/stdtypes.html#string-methods)
At first, this might not look any different from the documentation for a
function. Indeed, there are many similarities. Methods take
parameters that are documented in the same way as those for functions, for
example. In this particular case, we see that the center
method takes two parameters, one of which is optional. There is also a
purpose statement that defines what the method will do when it's called.
But let's take a closer look. The opening sentence of the purpose
statement indicates: "Return centered in a string of length width."
This begs the question: "What is it that is returned centered in a
string of length width?" Methods are called with an implicit
parameter that specifies the object on which the operation is to be
performed. Consider the following code segment:
>>> fname = 'Joe'
>>> lname = 'Jiang'
>>> fname.center(7, '*')
'**Joe**'
>>> lname.center(9, '^')
'^^Jiang^^'
First note that fname
and lname
each refer to a
string object. The statement fname.center(7, '*')
will, according to the documentation,
Return fname
centered in a string of length 7, padded with '*'
s.
And indeed that's what we got. In this case, fname
is
the implicit parameter. It specifies that the center
method is to be applied to the object referenced by fname
.
Similarly, lname.center(9, '^')
will return lname
centered in a string of length 9
, padded with '^'
s.
In this case, lname
is the implicit parameter.
We have stated that every piece of data in Python is an object -
even int
s and float
s. So, for example, the
float
class provides the following method, among others:
float.is_integer()
Return True
if the float instance is finite with integral
value, and False
otherwise:
>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False
New in version 2.6.
(http://docs.python.org/3/library/stdtypes.html#additional-methods-on-float)
The datetime
module
Now let's take a look at the documentation for a class that we have not yet
seen. Section
8.1.1 of the documentation for the datetime
module lists
the following classes, each of which defines a new type of data:
class datetime.date
class datetime.time
class datetime.datetime
class datetime.timedelta
class datetime.tzinfo
Let's consider the date
class. To create a date object,
we use a special method known as a constructor that has the same
name as the class:
class datetime.date(year, month, day)
All arguments are required. Arguments may be int
s or long
s,
in the following ranges:
MINYEAR <= year <= MAXYEAR
1 <= month
<= 12
1 <= day
<= number of days in the given month and year
If an argument outside those ranges is given, ValueError
is
raised.
(http://docs.python.org/3/library/datetime.html#datetime.date)
The following code segment illustrates the use of this constructor:
>>> d1 = datetime.date(2012, 5, 15)
>>> d2 = datetime.date(1984, 7, 11)
so d1
references the date object that represents the date May
15, 2012 while d2
references the date object that represents
the date July 11, 1984.
The documentation then lists a number of class methods that also
provide a way of constructing a date. For example, the today
method. A class method is a method that does not operate on a specific
instance of the class. However, it provides functionality that is
related to the class. It is invoked using the name of the class as
illustrated below:
>>> from datetime import date
>>> dt = date.today()
>>> print(dt)
2012-04-10
Pay particular attention to how this method was called:
date.today()
where date
is the name of the class, not a reference to an
instance of that class.
The Python documentation now lists class attributes. These are
constants that belong to the class. For example:
date.min
The earliest representable date, date(MINYEAR, 1, 1)
(http://docs.python.org/3/library/datetime.html#datetime.date)
Again, note that these class attributes are typically invoked using
the name of the class.
The documentation then goes on to list instance attributes.
Each instance of the class has its own copy of these attributes. Here
are some of the instance attributes associated with the date class:
date.year
Between MINYEAR
and MAXYEAR
inclusive.
date.month
Between 1 and 12 inclusive.
date.day
Between 1 and the number of days in the given month of the given year.
(http://docs.python.org/3/library/datetime.html#datetime.date)
On the surface, it may appear that there is no difference between date.min
and date.year
(or date.month
, date.day
).
However, date.min
was listed as a class
attribute whereas date.year
, date.month
and date.day
are described as instance attributes. Each object of type date
will have it's own copy of each of the instance attributes. However,
you can think of class attributes as shared among all objects of that
class.
Let's look at an example to illustrate the use of instance attributes:
>>> from datetime import date
>>> dt = date.today()
>>> print(dt.year) #print dt's year
2012
>>> bday = date(1990, 5, 12)
>>> print(bday.year) #print bday's year
1990
We create two date objects - one represents "today's" date (on whatever date
the code was run) and the other someone's birthday. We see that each
date object has a year attribute. The value of dt.year
is 2012 whereas the value of bday.year
is 1990.
Similarly, each date object has its own month and day
attributes.
As we have already noted, class attributes are typically invoked
using the name of the class but can also been invoked using an instance of
the class as illustrated below:
>>> from datetime import date
>>> print(date.min) # with name of class
0001-01-01
>>> dt = date.today()
>>> print(dt.min) # with instance of
class
0001-01-01
The documentation then goes on to describe supported operations on date
and timedelta
objects such as +
and -
.
Finally, the instance methods are presented. These methods operate on
an instance of the class. For example,
date.replace(year, month, day)
Return a date with the same value, except for those parameters given new
values by whichever keyword arguments are specified. For example, if
d == date(2002, 12, 31)
,
then
d.replace(day=26) == date(2002, 12, 26)
.
(http://docs.python.org/3/library/datetime.html#datetime.date)
The distinction between class methods and instance methods is similar to the
distinction between class attributes and instance attributes. Class
methods operate on class attributes only, not on an instance of the
class. They are typically invoked using the name of the class.
However, instance methods operate on instance attributes and are
therefore invoked using a reference to an instance of the class on which
that method will operate. As noted earlier, this instance is an
implicit parameter that is passed to the method when the method is
called. The following code segment illustrates the use of the replace
method:
>>> from datetime import date
>>> dt = date.today()
>>> print(dt)
2012-04-10
>>> dt.replace(month=5)
# replace the month in the date
object
# referenced by dt
>>>
print(dt)
2012-05-10
>>> bday = date(1990, 5, 12)
>>> bday.replace(day=14) # replace the day in the date object
# referenced by bday
>>> print(bday)
1990-05-14
Keep in mind that our focus in this course is on the use of existing
classes. You are not expected to be able to design new
classes.