Reading 5: Objects and Methods
A graphic representation of data abstracted from banks
of every computer in the human system.
Unthinkable complexity.
Lines of light ranged in the nonspace of the mind,
clusters and constellations of data.
Like city lights, receding.
- William Gibson, Neuromancer
Overview
We've covered many of the essential aspects of Python programming, but we still have a way to go! In this reading we'll talk about what an "object" is, what "methods" do and how they are related to functions, and how Python is an "object-oriented language". We will use strings as a simple example of an object, but we will see many more kinds of objects later on.
Info
In fact, in Python all data are represented as objects. Even functions are objects.
Topics
-
Terminal input using the
input
function -
Objects and methods
Terminal input
This is not really about objects and methods,
but we have to put it somewhere,
so we're putting it here .
We'd like to be able to write interactive programs,
where you (the user) and the program have a "dialogue".
You do something, the program responds,
you respond to the program, and so forth.
There are many ways to do this,
but the most basic way is to allow the program
to read a line of input typed at the terminal.
When the program wants a response from you,
it asks you for a line of input.
You type it in and hit the return key,
then the program does something with that line of input, and so on.
In Python, we do this using the input
function:
Note
We've put asterisks around the text that you would type
into the terminal for the input()
function call.
You wouldn't actually type the asterisks.
The line under the input()
call
is what you type literally at the keyboard (try it!).
When you're done, hit the return key
and Python prints the string it received.
This isn't how you actually use input
, of course.
You almost always store the line read into a variable:
Now you can use the value of answer
to do something in your program.
One other thing that would be nice is if input
could print a prompt,
which is a string that indicates what it is expecting of you.
To use a prompt, add a string argument to input
:
>>> answer = input('Please answer "yes" or "no": ')
Please answer "yes" or "no": *yes*
>>> answer
'yes'
The only thing that the user entered in this example was the word yes
,
which becomes the value of the answer
variable.
Question
-
Why are the words
"yes"
and"no"
in the prompt string written with double quotes? -
Why is there a blank space at the end of the prompt string?
Type this example into Python yourself,
and play around with it to get familiar with how the input
function works.
Using input
to input integers and other non-strings
One thing to be careful about is that input
always returns a string,
even if you intended it to return e.g. an integer.
For instance, look at this code:
i = input('Enter an integer: ')
j = input('Enter another integer: ')
print('The sum of the two integers is {}'.format(i + j))
Here's a sample run:
What went wrong?
Remember, computer languages are dumb
and they don't know what you want them to do
unless you spell it out exactly.
Here, the input
function always returns a string,
so the variables i
and j
contain the strings '42'
and '101'
,
respectively.
When you "add" two strings, you actually concatenate them,
so you get the result '42101'
.
To avoid this, you have to tell Python
to convert the result of the input
call to an integer
using the int
conversion function.
Here's the right way to do this:
i = int(input('Enter an integer: '))
j = int(input('Enter another integer: '))
print('The sum of the two integers is {}'.format(i + j))
Now look at what happens when we run it:
This time it works,
because of the calls to the int
function
which converts the string output from input
to integers.
Again, please play around with this in the interpreter
so you understand exactly how it works.
You can convert strings to more than just integers.
You can also convert strings to floating-point numbers
with the float
function:
Exceptions
You might wonder what happens if you try to convert a string to a float (or an integer) which is not the string representation of a valid float (or integer). For example:
>>> pi = float('foobar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: 'foobar'
In this case, Python handles the error by raising an exception and printing a traceback. We will talk a lot more about exceptions and traceback in future readings.
OK, that's enough about input
. On to objects!
Objects and methods
You've probably heard the term "object-oriented" as in "Python (or Java, or C++) is an object-oriented programming language". What does that mean?
The exact meaning of "object-oriented" differs between languages, but for Python, it means that all data values are represented as objects. OK, great, so what is an object?
An object is some kind of Python data along with some associated functions that act on the data. (You can think of the data and the functions as begin "bound together" to create an object.) The functions that act on the object are called methods to distinguish them from regular functions. Unlike a function, a method "belongs" to a particular object and has access to the object's internal components.1
Let's look at the syntax of method calls.
Method call syntax ("dot syntax")
We know that function calls have a very specific syntax: the name of the function, followed by a list of arguments in parentheses. Multiple arguments to a function are separated by commas. So function calls looks like this:
and so on.
Method calls are almost exactly the same,
except that instead of the name of the function,
we have the name of the object,
a dot (.
) and the name of the method.
Here are some hypothetical method calls
on a hypothetical object called obj
:
Method calls are like function calls on an object. If you like, you can think of the object as an extra argument to the method that happens to be placed in a weird location (before the dot).
I call the obj.method
kind of syntax for method calls the "dot syntax".
As we'll see in later readings,
this syntax is used for more than just method calls,
though the other uses are similar.
Strings are objects
We've actually been working with Python objects already. Since all Python values are objects, even things like integers are objects (but we don't usually use methods on integers). Strings are also objects, and there are a number of useful methods defined for strings. For instance:
The upper
method on strings converts a string to its uppercase version.
(Note that it doesn't change the string, because strings are immutable;
it simply creates a new string with the same characters but uppercased).
Notice that you can call a method on a literal value (like 'spam'
)
or on a variable that stands for that value (like s
).
Most of the time, we use methods on variables,
but in this reading we'll often use methods
on literal strings for convenience.
Since methods are like functions, they have an argument list.
In this case, the argument list is empty,
so we have to put the open/close parentheses ()
after the name of the method.
It's pretty common to have methods that take no arguments;
what that means is that the method
only needs the name of the object to do what it's doing.
In this case, all the upper
method needs to know about
is the string object itself.
You might think that it's dumb that you have to include an empty pair of open/close parentheses to call a method with no arguments. But if you leave them off, the method never gets called:
Python is basically saying here "yup, that's a method all right". If you want it to do something, you need the parentheses.2
Here are some other methods on strings:
>>> 'SPAM'.lower()
'spam'
>>> 'spam'.islower()
True
>>> ' string with spaces on each end '.strip()
'string with spaces on each end'
>>> 'Caltech'.endswith('tech')
True
Info
Python uses the special names True
and False
to stand for boolean (true/false) values.
Notice in particular the call to the endswith
method.
This is the first method call we've seen
that has an argument in its argument list.
A full list of Python's string methods can be found here. You're not expected to memorize them! Some of the more useful ones include:
capitalize
startswith
andendswith
find
format
(we've seen this already)index
join
lower
andupper
strip
Exercise
Pick three methods from the above list and look up their definitions. Don't memorize them; just remember enough so that when you come across a situation where they might be useful, you'll know where to look.
Methods vs. functions
Let's take a closer look at the endswith
method:
You might wonder why this wasn't written as a regular function, e.g. something like this:
>>> endswith('Caltech', 'tech') # Doesn't work!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'endswith' is not defined
Python is telling you that there is no endswith
function.
In fact, endswith
could have been written that way.
Or you could define it that way if you really wanted to:
There's no reason to do this, though. One benefit of using methods instead of functions is that you can use the same method name on different objects and have it mean different things for each object. Usually, though, it's better if the meaning is similar (even if it's not identical), because otherwise it's likely to be confusing. Not having to define new names for similar (but not identical) functionality means that code reads better and is more intuitive.
Defining methods
We will not go into the syntax for defining methods at this time. In fact, it's almost identical to function definition syntax. For now, and for most of this course, we will use pre-written methods. Python's extensive code libraries (called modules) and many built-in data structures mean that there are a lot of pre-written methods we can use right away.
The len
function
As we mentioned above, there are many function-like things that can be written either as methods or as functions, at least in principle. Python is not always totally consistent in this regard.3 Some things are written as functions, and others as methods, and sometimes you find the same functionality is provided by both a function and a method. Usually, though, a particular behavior is implemented as one or the other.
As if this wasn't confusing enough,
consider the very useful built-in len
function.
(Notice that I said function, not method.)
len
takes a single argument and returns its "length",
whatever "length" means for that kind of data.
We can use len
on a lot of different kinds of Python objects.
For instance, strings have a length:
For a string, its len
is the number of characters in the string.
On the other hand, integers and boolean values don't have a len
:
>>> len(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>> len(True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'bool' has no len()
Lists (which are another data type that we'll meet shortly) also have a length:
(Here, [1, 2, 3]
is Python's syntax for a list of three integers:
1
, 2
, and 3
.)
So len
works on both strings and lists,
but it should be clear that finding the length of a string
is a different kind of operation than finding the length of a list.
You might think, therefore,
that Python should have made len
a method on strings and lists,
not a function.
Why didn't it?
Well, actually, it did but it pretends that it didn't.
When you say len(x)
in Python,
it internally calls a method called __len__
on the object.
Observe:
The only reason len
is a function is that it's used so often
that the Python designer (Guido van Rossum)
figured that it would be more pleasant to write it
like a function than like a method.
You can agree with this or not, but that's how it is.4
What's more interesting is that
this is a good example of a method (__len__
)
which has the same name for two different kinds of objects
(strings and lists) but which does different things in each case.
Both things are conceptually "lengths" but the details are different.
This is common with methods:
each object can use the same method names as other objects,
but the meaning of these methods is specific to the object.
Special methods
One last thing:
the __len__
method uses a naming convention that we'll see again.
Names of methods that are used internally by Python
for some important purpose are, by convention,
written with two leading and two trailing underscores.
There are a bunch of "special methods" like this that do a number of things,
and we'll meet some more of them very soon.
Be aware, though, that this is only a convention.
You could write your own methods with names like this,
and Python would still accept it.
However, please don't do that!
If you redefined a method like __len__
,
your program will probably fail,
and it might be very hard for you to figure out why.
-
That is, assuming the object has any internals. Some very simple objects, like integers, don't have any internal components. ↩
-
Some object-oriented languages, like Ruby, don't require you to use parentheses for methods with no arguments. You can waste an incredible amount of time arguing over whether this is a good or a bad thing. ↩
-
Some languages, like Java or Ruby, try hard to be "pure" object-oriented languages. Python is more pragmatic; Python programmers use whatever seems best for the application at hand. ↩
-
Every programming language has some features in it that some people don't like. Most have features that almost everyone doesn't like. Python is very good, but it isn't perfect. Features in a programming languages that most programmers dislike are commonly referred to as warts. Compared to most languages, Python has very few warts. ↩