Originally Published: Wednesday, 30 August 2000 Author: Jason Tackaberry
Published to: develop_articles_tutorials/Development Tutorials Page: 2/6 - [Printable]

Programming with Python - Part 1: Baby Steps

This tutorial is the first in a series that will introduce you to Python, a dynamic, object-oriented language that is rapidly gaining popularity. Since I myself have garnered a modest Perl background before learning Python, I will target this tutorial at the Perl programmer. However, anyone with a little programming experience should find this text useful.

The Basics  << Page 2 of 6  >>

The Basics

Now we know how to start a Python program, and hopefully by now have gotten over the shock from the indentation requirement. There's a few things we need to have under our belts before we can dive in.

First, in Python, mostly everything is an object. Strings are objects, integers are objects, functions are objects, lists are objects, and so on. Some objects may be acted on directly; that is, these objects have methods that may be invoked. For example, list objects have an append method that let you append an object to the list. Other objects, such as strings and integers, must be operated on indirectly. So, you won't call a string's split method, but instead will use the split function offered by the string library (module). This idiosyncrasy has been addressed somewhat in Python 1.6 (at least, string objects now have methods), but in general knowing what's what is just a matter of memory work.

Python objects come in two flavors: mutable, and immutable. Immutable objects are those objects which cannot be directly changed, such as strings or integers. If you want to concatenate some text onto a string, you don't modify a string object. Instead, you concatenate two string objects together and produce a new string object. Mutable objects can be modified directly. Lists, for example, are mutable. Adding an item to a list does not produce a new list object, it just modifies the list you're working with.

Like Perl, Python has all the high level data types we've come to know and love. Tuples are much like lists in an array context in Perl, except that they are immutable. For example, (1, 2, 3, "foo", "bar", "baz") is a tuple construct. Python lists are more like Perl lists because they are mutable. What's the point of the tuple data type, you ask? Immutable types are easier to build internally, they have a simpler interface, and they are much more efficient. Why incur the overhead of a list when only a tuple is needed, such as with return values for example? Finally, Python offers dictionaries, associative arrays which Perl coders will know as hash tables. Let's have a look at some code that uses all three of these data structures:

  stuff = (1, 2, 3, "foo", "bar", "baz") # this is a tuple with 6 elements
  list = [] # initialize an empty list
  ages = { "Dick": 36, "Jane": 25, "John": 20 } # a dictionary

  # Go through the tuple and append only the strings onto the list
  for element in stuff:
    if type(element) == types.StringType:
      list.append(element)

  # Now list all the people and their ages from the ages dictionary
  for person in ages.keys():
    print person, "is", ages[person], "years old"

This example shows us not only tuples, lists, and dictionaries, but introduces some iteration and selection constructs. The for statement iterates through any sequence object (either a list, tuple, or string) and executes the code block that follows it. In the first instance, the for loop will iterate across each of the items in the stuff tuple. The first time through, element becomes 1, and then 2, and so on, until it finally finishes baz. The second for loop iterates over all the keys in the ages dictionary. The keys are those things that you want to look up, or index, in the dictionary. So, the person variable takes on the values of Dick, Jane, and John (in no particular order).

The block under the first for loop shows an if construct. The syntax of this line should be fairly intuitive, especially if you have a Perl or C background. Equality comparisons are done using the == operator; inequality is tested using !=; other unary, binary, bit-wise, and shifting operators work as you would expect. The only operators Python lacks that you may miss are the increment and decrement operators (++ and --, respectively), and the shorthand assignment operators, like +=, -=, and so on. I cringe every time I am forced to use a = a + 1 instead of a++; supposedly these operators were not included to improve readability, but the jury's still out on that one. However, these augmented assignment operators will at long last be included in Python 2.0. Comparison operators may act on any object, and will behave differently depending on the context. Comparisons between integers will do arithmetic comparisons; comparisons between strings will do lexical comparisons; comparisons between tuples will perform element-by-element comparisons; and so on. There's nothing particularly magical about an if statement. The code block that follows it is executed if the expression is evaluated to true.

Another iteration method you're probably familiar with is the while statement:

  i = 10
  while i > 0:
    i = i - 1

And this does precisely what you'd expect. The while statement evaluates the expression (in this case i > 0), and executes the block of code that follows if it evaluates to true.

The syntax for defining functions is equally as simple. For example:

  def say_hello(who, what):
    print "Hello,", who, "! ", what

And calling say_hello("Fred", "How are you?") will output Hello Fred! How are you?

Just in case you haven't noticed yet (I'm sure you have), variables in Python aren't explicitly assigned types, as is the case with any loosely typed language. The type, be it string, list, integer, or whatever, is bound to the variable on the fly. If you're a Perl coder, this may seem a little backwards to you. In Perl, the type of a variable is determined by the lvalue in an expression (the part on the left side of the assignment, in this case). For example:

  my %result = get_some_value();

Here the type of variable result is determined by lvalue of this expression, in this case a hash table. If the return value of get_some_value() is not a hash, then Perl will try to coerce it to one. Also, in Perl, $result is distinct and different from %result and @result. If you're not a Perl coder and don't know what any of this means, don't worry. Just understand that in Python, the type of a variable is determined by the rvalue of an expression ((the part on the right side of the assignment). So if get_some_value() returns a tuple, the type of result is bound to a tuple. If it returns a string, result becomes a string type, and so on.

If you're coming from strictly a C++ background, you're about to discover the way polymorphism was meant to be. I'm going to conveniently sidestep a heated debate about whether static typing makes for better software engineering. Personally, I find loosely-typed languages a pleasure to work with.





The Basics  << Page 2 of 6  >>