images

This is a minimal introduction to Python, based on my popular web tutorial, “Instant Python” (http://hetland.org/writing/instant-python.html). It targets programmers who already know a language or two, but who want to get up to speed with Python. For information on downloading and executing the Python interpreter, see Chapter 1.

The Basics

To get a basic feel for the Python language, think of it as pseudocode, because that’s pretty close to the truth. Variables don’t have types, so you don’t need to declare them. They appear when you assign to them, and disappear when you don’t use them anymore. Assignment is done with the = operator, like this:

x = 42

Note that equality is tested by the == operator.

You can assign several variables at once, like this:

x,y,z = 1,2,3
first, second = second, first
a = b = 123

Blocks are indicated through indentation, and only through indentation. (No begin/end or braces.) The following are some common control structures:

if x < 5 or (x > 10 and x < 20):
    print "The value is OK."

if x < 5 or 10 < x < 20:
    print "The value is OK."

for i in [1,2,3,4,5]:
    print "This is iteration number", i

x = 10
while x >= 0:
    print "x is still not negative."
    x = x-1

The first two examples are equivalent.

The index variable given in the for loop iterates through the elements of a list1 (written with brackets, as in the example). To make an “ordinary” for loop (that is, a counting loop), use the built-in function range:

# Print out the values from 0 to 99, inclusive
for value in range(100):
    print value

The line beginning with # is a comment and is ignored by the interpreter.

Now you know enough (in theory) to implement any algorithm in Python. Let’s add some basic user interaction. To get input from the user (from a text prompt), use the built-in function input:

x = input("Please enter a number: ")
print "The square of that number is", x*x

The input function displays the (optional) prompt given and lets the user enter any valid Python value. In this case, we were expecting a number. If something else (such as a string) is entered, the program would halt with an error message. To avoid that, you would need to add some error checking. I won’t go into that here; suffice it to say that if you want the user input returned verbatim as a string (so that anything can be entered), use the function raw_input instead. If you wanted to convert an input string s to an integer, you could then use int(s).

imagesNote  If you want to input a string with input, the user must write the quotes explicitly. In Python, strings can be enclosed in either single or double quotes. In Python 3.0, the original input disappears, and raw_input is renamed input. See Appendix D for more on Python 3.0.

So, you have control structures, input, and output covered—now you need some snazzy data structures. The most important ones are lists and dictionaries. Lists are written with brackets, and can (naturally) be nested:

name = ["Cleese", "John"]
x = [[1,2,3],[y,z],[[[]]]]

One of the nice things about lists is that you can access their elements separately or in groups, through indexing and slicing. Indexing is done (as in many other languages) by writing the index in brackets after the list. (Note that the first element has index 0.)

print name[1], name[0] # Prints "John Cleese"
name[0] = "Smith"

Slicing is almost like indexing, except that you indicate both the start and stop index of the result, with a colon (:) separating them:

x = ["SPAM","SPAM","SPAM","SPAM","SPAM","eggs","and","SPAM"]
print x[5:7] # Prints the list ["eggs","and"]

Notice that the end is noninclusive. If one of the indices is dropped, it is assumed that you want everything in that direction. In other words, the slice x[:3] means “every element from the beginning of x up to element 3, noninclusive” (well, element 3 is actually the fourth element, because the counting starts at 0). The slice x[3:] would, on the other hand, mean “every element in x, starting at element 3 (inclusive) up to, and including, the last one.” For really interesting results, you can use negative numbers, too: x[-3] is the third element from the end of the list.

Now then, what about dictionaries? To put it simply, they are like lists, except that their contents aren’t ordered. How do you index them then? Well, every element has a key, or a name, which is used to look up the element, just as in a real dictionary. The following example demonstrates the syntax used to create dictionaries:

phone = { "Alice" : 23452532, "Boris" : 252336,
          "Clarice" : 2352525, "Doris" : 23624643 }

person = { 'first name': "Robin", 'last name': "Hood",
           'occupation': "Scoundrel" }

Now, to get person’s occupation, you use the expression person["occupation"]. If you wanted to change the person’s last name, you could write this:

person['last name'] = "of Locksley"

Simple, isn’t it? Like lists, dictionaries can hold other dictionaries, or lists, for that matter. And naturally, lists can hold dictionaries, too. That way, you can easily make some quite advanced data structures.

Functions

Our next step is abstraction. You want to give a name to a piece of code and call it with a couple of parameters. In other words, you want to define a function (also called a procedure). That’s easy. Use the keyword def, as follows:

def square(x):
    return x*x

print square(2) # Prints out 4

The return statement is used to return a value from the function.

When you pass a parameter to a function, you bind the parameter to the value, thus creating a new reference. This means that you can modify the original value directly inside the function, but if you make the parameter name refer to something else (rebind it), that change won’t affect the original. This works just like in Java, for example. Let’s take a look at an example:

def change(x):
    x[1] = 4

y = [1,2,3]
change(y)
print y # Prints out [1,4,3]

As you can see, the original list is passed in, and if the function modifies it, these modifications carry over to the place where the function was called. Note the behavior in the following example, however, where the function body rebinds the parameter:

def nochange(x):
    x = 0

y = 1
nochange(y)
print y # Prints out 1

Why doesn’t y change now? Because you don’t change the value! The value that is passed in is the number 1, and you can’t change a number in the same way that you change a list. The number 1 is (and will always be) the number 1. What the example does change is what the parameter x refers to, and this does not carry over to the calling environment.

Python has all kinds of nifty things such as named arguments and default arguments, and can handle a variable number of arguments to a single function. For more information about this, see Chapter 6.

If you know how to use functions in general, what I’ve told you so far is basically what you need to know about them in Python.

It might be useful to know, however, that functions are values in Python. So if you have a function such as square, you could do something like the following:

queeble = square
print queeble(2) # Prints out 4

To call a function without arguments, you must remember to write doit() and not doit. The latter, as shown, only returns the function itself, as a value. This goes for methods in objects, too. Methods are described in the next section.

Objects and Stuff . . .

I assume you know how object-oriented programming works. Otherwise, this section might not make much sense. No problem—start playing without the objects, or check out Chapter 7.

In Python, you define classes with the (surprise!) class keyword, as follows:

class Basket:

    # Always remember the *self* argument
    def __init__(self, contents=None):
        self.contents = contents or []

    def add(self, element):
        self.contents.append(element)

    def print_me(self):
        result = ""
        for element in self.contents:
            result = result + " " + repr(element)
        print "Contains:" + result

Several things are worth noting in this example:

  • Methods are called like this: object.method(arg1, arg2).
  • Some arguments can be optional and given a default value (as mentioned in the previous section on functions). This is done by writing the definition like this:
    def spam(age=32): ...
  • Here, spam can be called with one or zero parameters. If it’s called without any parameters, age will have the default value of 32.
  • repr converts an object to its string representation. (So if element contains the number 1, then repr(element) is the same as "1", whereas 'element' is a literal string.)

No methods or member variables (attributes) are protected (or private or the like) in Python. Encapsulation is pretty much a matter of programming style. (If you really need it, there are naming conventions that will allow some privacy, such as prefixing a name with a single or double underscore.)

Now, about that short-circuit logic . . .

All values in Python can be used as logic values. Some of the more empty ones (such as False, [], 0, "", and None) represent logical falsity; most other values (such as True, [0], 1, and "Hello, world") represent logical truth.

Logical expressions such as a and b are evaluated like this:

  • Check if a is true.
  • If it is not, then simply return it.
  • If it is, then simply return b (which will represent the truth value of the expression).

The corresponding logic for a or b is this:

  • If a is true, then return it.
  • If it isn’t, then return b.

This short-circuit mechanism enables you to use and and or like the Boolean operators they are supposed to implement, but it also enables you to write short and sweet little conditional expressions. For example, this statement:

if a:
    print a
else:
    print b

could instead be written like this:

print a or b

Actually, this is somewhat of a Python idiom, so you might as well get used to it.

imagesNote  In Python 2.5, actual conditional expressions were introduced, so you could, in fact, write this:

print a if a else b

The Basket constructor (Basket.__init__) in the previous example uses this strategy in handling default parameters. The argument contents has a default value of None (which is, among other things, false); therefore, to check if it had a value, you could write this:

if contents:
    self.contents = contents
else:
    self.contents = []

Instead, the constructor uses this simple statement:

self.contents = contents or []

Why don’t you give it the default value of [] in the first place? Because of the way Python works, this would give all the Basket instances the same empty list as default contents. As soon as one of them started to fill up, they all would contain the same elements, and the default would not be empty anymore. To learn more about this, see the discussion about the difference between identity and equality in Chapter 5.

imagesNote  When using None as a placeholder as done in the Basket.__init__ method, using contents is None as the condition is safer than simply checking the argument’s Boolean value. This will allow you to pass in a false value such as an empty list of your own (to which you could keep a reference outside the object).

If you would like to use an empty list as the default value, you can avoid the problem of sharing this among instances by doing the following:

def __init__(self, contents=[]):
    self.contents = contents[:]

Can you guess how this works? Instead of using the same empty list everywhere, you use the expression contents[:] to make a copy. (You simply slice the entire thing.)

So, to actually make a Basket and to use it (to call some methods on it), you would do something like this:

b = Basket(['apple','orange'])
b.add("lemon")
b.print_me()

This would print out the contents of the Basket: an apple, an orange, and a lemon.

There are magic methods other than __init__. One such method is __str__, which defines how the object wants to look if it is treated like a string. You could use this in the basket instead of print_me:

def __str__(self):
    result = ""
    for element in self.contents:
        result = result + " " + repr(element)
    return "Contains:" + result

Now, if you wanted to print the basket b, you could just use this:

print b

Cool, huh?

Subclassing works like this:

class SpamBasket(Basket):
    # ...

Python allows multiple inheritance, so you can have several superclasses in the parentheses, separated by commas. Classes are instantiated like this: x = Basket(). Constructors are, as I said, made by defining the special member function __init__. Let’s say that SpamBasket had a constructor __init__(self, type). Then you could make a spam basket like this: y = SpamBasket("apples").

If in the constructor of SpamBasket, you needed to call the constructor of one or more superclasses, you could call it like this: Basket.__init__(self). Note that in addition to supplying the ordinary parameters, you must explicitly supply self, because the superclass __init__ doesn’t know which instance it is dealing with.

For more about the wonders of object-oriented programming in Python, see Chapter 7.

Some Loose Ends

Here, I’ll quickly review a few other useful things before ending this appendix. Most useful functions and classes are put in modules, which are really text files with the file name extension .py that contain Python code. You can import these and use them in your own programs. For example, to use the function sqrt from the standard module math, you can do either this:

import math
x = math.sqrt(y)

or this:

from math import sqrt
x = sqrt(y)

For more information on the standard library modules, see Chapter 10.

All the code in the module/script is run when it is imported. If you want your program to be both an importable module and a runnable program, you might want to add something like this at the end of it:

if __name__ == "__main__": main()

This is a magic way of saying that if this module is run as an executable script (that is, it is not being imported into another script), then the function main should be called. Of course, you could do anything after the colon there.

And for those of you who want to make an executable script in UNIX, use the following first line to make it run by itself:

#!/usr/bin/env python

Finally, a brief mention of an important concept: exceptions. Some operations (such as dividing something by zero or reading from a nonexistent file) produce an error condition or exception. You can even make your own exceptions and raise them at the appropriate times.

If nothing is done about the exception, your program ends and prints out an error message. You can avoid this with a try/except statement, as in this example:

def safe_division(a, b):
    try:
        return a/b
    except ZeroDivisionError: pass

ZeroDivisionError is a standard exception. In this case, you could have checked if b was zero, but in many cases, that strategy is not feasible. And besides, if you removed the try/except statement in safe_division, thereby making it a risky function to call (called something like unsafe_division), you could still do the following:

try:
    unsafe_division(a, b)
except ZeroDivisionError:
    print "Something was divided by zero in unsafe_division"

In cases in which you typically would not have a specific problem, but it might occur, using exceptions enables you to avoid costly testing and so forth.

Well, that’s it. Hope you learned something. Now go and play. And remember the Python motto of learning: use the source (which basically means read all the code you can get your hands on).

__________

1.  Or any other iterable object, actually.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset