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 ints and floats.  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 ints or longs, 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.