Python 101 -- Introduction to Python

Dave Kuhlman

http://www.rexx.com/~dkuhlman
Email:

Release 1.01
August 7, 2008


Front Matter

Copyright (c) 2003 Dave Kuhlman

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Abstract:

This document is a syllabus for a first course in Python programming. This course contains an introduction to the Python language, instruction in the important and commonly used features of the language, and practical excercises in the use of those features.


Contents


1. Python 101 -- Introduction to Python

Python is a high-level general purpose programming language. Because code is automatically compiled to byte code and executed, Python is suitable for use as a scripting language, Web application implementation language, etc. Because Python can be extended in C and C++, Python can provide the speed needed for even compute intensive tasks.

1.1 Important Features of Python

Some things you will need to know:

1.2 Where to Go For Additional help


2. Python -- Feature by Feature

2.1 Interactive Python

If you execute Python from the command line with no script, Python gives you an interactive prompt. This is an excellent facility for learning Python and for trying small snippets of code. Many of the examples that follow were developed using the Python interactive prompt.

In addition, there are tools that will give you a more powerful and fancy Python interactive mode. One example is IPython, which is available at http://ipython.scipy.org/. You may also want to consider using IDLE. IDLE is a graphical integrated development environment for Python; it contains a Python shell. You will find a script to start up IDLE in the Tools/scripts directory of your Python distribution. IDLE requires Tkinter.

2.2 Data Types

2.2.1 Strings

2.2.1.1 What

In Python, strings are immutable sequences of characters. They are immutable in that in order to modify a string, you must produce a new string.

2.2.1.2 When

Any text information.

2.2.1.3 How

Create a new string from a constant:

s1 = 'abce'
s2 = "xyz"
s3 = """A
multi-line
string.
"""

Use any of the string methods, for example:

>>> 'The happy cat ran home.'.upper()
'THE HAPPY CAT RAN HOME.'
>>> 'The happy cat ran home.'.find('cat')
10
>>> 'The happy cat ran home.'.find('kitten')
-1
>>> 'The happy cat ran home.'.replace('cat', 'dog')
'The happy dog ran home.'

Type "help(str)" or see http://www.python.org/doc/current/lib/string-methods.html for more information on string methods.

You can also use the equivalent functions from the string module. For example:

>>> import string
>>> s1 = 'The happy cat ran home.'
>>> string.find(s1, 'happy')
4

See http://www.python.org/doc/current/lib/module-string.htmlfor more information on the string module.

There is also a string formatting operator: "%".

>>> state = 'California'
>>> 'It never rains in sunny %s.' % state
'It never rains in sunny California.'

You can use any of the following formatting characters:

Conversion Meaning Notes
d Signed integer decimal.
i Signed integer decimal.
o Unsigned octal. (1)
u Unsigned decimal.
x Unsigned hexidecimal (lowercase). (2)
X Unsigned hexidecimal (uppercase). (2)
e Floating point exponential format (lowercase).
E Floating point exponential format (uppercase).
f Floating point decimal format.
F Floating point decimal format.
g Same as "e" if exponent is greater than -4 or less than precision, "f" otherwise.
G Same as "E" if exponent is greater than -4 or less than precision, "F" otherwise.
c Single character (accepts integer or single character string).
r String (converts any python object using repr()). (3)
s String (converts any python object using str()). (4)
% No argument is converted, results in a "%" character in the result.

And these flags:

Flag Meaning
# The value conversion will use the ``alternate form'' (where defined below).
0 The conversion will be zero padded for numeric values.
- The converted value is left adjusted (overrides the "0" conversion if both are given).
  (a space) A blank should be left before a positive number (or empty string) produced by a signed conversion.
+ A sign character ("+" or "-") will precede the conversion (overrides a "space" flag).

See http://www.python.org/doc/current/lib/typesseq-strings.htmlfor more information on string formatting.

You can also write strings to a file and read them from a file. Here are some examples:

A few additional comments about strings:

2.2.2 Sequences

2.2.2.1 What

There are several types of sequences in Python. We've already discussed strings. In this section we will describe lists and tuples. See http://www.python.org/doc/current/lib/typesseq.html for a description of the other sequence types (e.g. buffers and xrange objects).

Lists are dynamic arrays. They are arrays in the sense that you can index items in a list (for example "mylist[3]") and you can select sub-ranges (for example "mylist[2:4]"). They are dynamic in the sense that you can add and remove items after the list is created.

Tuples are light-weight lists, but differ from lists in that they are immutable. That is, once a tuple has been created, you cannot modify it. You can, of course, modify any (modifiable) objects that the tuple refers to.

Capabilities of lists:

Capabilities of lists and tuples:

2.2.2.2 When

2.2.2.3 How

To create a list use:

>>> items = [111, 222, 333]
>>> items
[111, 222, 333]

To add an item to the end of a list, use:

>>> items.append(444)
>>> items
[111, 222, 333, 444]

To insert an item into a list, use:

>>> items.insert(0, -1)
>>> items
[-1, 111, 222, 333, 444]

You can also push items onto the right end of a list and pop items off the right end of a list with append and pop.

>>> items.append(555)
>>> items
[-1, 111, 222, 333, 444, 555]
>>> items.pop()
555
>>> items
[-1, 111, 222, 333, 444]

And, you can iterate over the items in a list with the for statement:

>>> for item in items:
...   print 'item:', item
...
item: -1
item: 111
item: 222
item: 333
item: 444

2.2.3 Dictionaries

2.2.3.1 What

Associative arrays.

Capabilities:

For help on dictionaries, type:

>>> help dict

at Python's interactive prompt, or:

$ pydoc help

at the command line.

2.2.3.2 When

2.2.3.3 How

Create a dictionary with:

>>> lookup = {}
>>> lookup
{}

or:

>>> def fruitfunc():
...    print "I'm a fruit."
>>> def vegetablefunc():
...    print "I'm a vegetable."
>>>
>>> lookup = {'fruit': fruitfunc, 'vegetable': vegetablefunc}
>>> lookup
{'vegetable': <function vegetablefunc at 0x4028980c>,
'fruit': <function fruitfunc at 0x4028e614>}
>>> lookup['fruit']()
I'm a fruit.
>>> lookup['vegetable']()
I'm a vegetable.

or:

>>> lookup = dict((('aa', 11), ('bb', 22), ('cc', 33)))
>>> lookup
{'aa': 11, 'cc': 33, 'bb': 22}
>>>

Test for the existence of a key with:

>>> if lookup.has_key('fruit'):
...   print 'contains key "fruit"'
...
contains key "fruit"
>>>

or:

>>> if 'fruit' in lookup:
...   print 'contains key "fruit"'
...
contains key "fruit"
>>>

Access the value of a key as follows:

>>> print lookup['fruit']
<function fruitfunc at 0x4028e614>
>>>

>>> for key in lookup:
...     print 'key: %s' % key
...     lookup[key]()
...
key: vegetable
I'm a vegetable.
key: fruit
I'm a fruit.
>>>

And, remember that you can sub-class dictionaries. Here are two versions of the same example. The keyword arguments in the second version require Python 2.3 or later:

#
# This example works with Python 2.2.
class MyDict_for_python_22(dict):
    def __init__(self, **kw):
        for key in kw.keys():
            self[key] = kw[key]
    def show(self):
        print 'Showing example for Python 2.2 ...'
        for key in self.keys():
            print 'key: %s  value: %s' % (key, self[key])

def test_for_python_22():
    d = MyDict_for_python_22(one=11, two=22, three=33)
    d.show()

test_for_python_22()

#
# This example works with Python 2.3.
#   Keyword support, when subclassing dictionaries, seems to have
#   been enhanced in Python 2.3.
class MyDict(dict):
    def show(self):
        print 'Showing example for Python 2.3 ...'
        for key in self.keys():
            print 'key: %s  value: %s' % (key, self[key])

def test():
    d = MyDict(one=11, two=22, three=33)
    d.show()

test()

Running this example produces:

Showing example for Python 2.2 ...
key: one  value: 11
key: three  value: 33
key: two  value: 22
Showing example for Python 2.3 ...
key: three  value: 33
key: two  value: 22
key: one  value: 11

A few comments about this example:

2.3 Simple Statements

2.3.1 print

The print statement sends output to stdout.

Here are a few examples:

print obj
print obj1, obj2, obj3
print "My name is %s" % name

Notes:

More information on the print statement is at http://www.python.org/doc/current/ref/print.html.

Note: Note to Jython users - Jython does not appear to support the file constructor for files. In the above example, replace file with open.

2.3.2 import

The import statement makes a module and its contents available for use.

Here are several forms of the import statement:

import test
Import module test. Refer to x in test with "test.x".

from test import x
Import x from test. Refer to x in test with "x".

from test import *
Import all objects from test. Refer to x in test with "x". This form of import is usually not recommended.

import test as theTest
Import test; make it available as theTest. Refer to object x with "theTest.x".

A few comments about import:

More information on import at http://www.python.org/doc/current/ref/import.html.

2.3.3 assert

Use the assert statement to place error checking statements in you code. Here is an example:

def test(arg1, arg2):
    arg1 = float(arg1)
    arg2 = float(arg2)
    assert arg2 != 0, 'Bad dividend -- arg1: %f arg2: %f' % (arg1, arg2)
    ratio = arg1 / arg2
    print 'ratio:', ratio

When arg2 is zero, running this code will produce something like the following:

Traceback (most recent call last):
  File "tmp.py", line 22, in ?
    main()
  File "tmp.py", line 18, in main
    test(args[0], args[1])
  File "tmp.py", line 8, in test
    assert arg2 != 0, 'Bad dividend -- arg1: %f arg2: %f' % (arg1, arg2)
AssertionError: Bad dividend -- arg1: 2.000000 arg2: 0.000000

A few comments:

2.3.4 global

The problem -- Imagine a global variable NAME. If, in a function, the first mention of that variable is "name = NAME", then I'll get the value of the the global variable NAME. But, if, in a function, my first mention of that variable is an assignment to that variable, then I will create a new local variable, and will not refer to the global variable at all. Consider:

NAME = "Peach"

def show_global():
    name = NAME
    print '(show_global) name: %s' % name

def set_global():
    NAME = 'Nectarine'
    name = NAME
    print '(set_global) name: %s' % name

show_global()
set_global()
show_global()

Running this code produces:

(show_global) name: Peach
(set_global) name: Nectarine
(show_global) name: Peach

The set_global modifies a local variable and not the global variable as I might have intended.

The solution -- How can I fix that? Here is how:

NAME = "Peach"

def show_global():
    name = NAME
    print '(show_global) name: %s' % name

def set_global():
    global NAME
    NAME = 'Nectarine'
    name = NAME
    print '(set_global) name: %s' % name

show_global()
set_global()
show_global()

Notice the global statement in function set_global. Running this code does modify the global variable NAME, and produces the following output:

(show_global) name: Peach
(set_global) name: Nectarine
(show_global) name: Nectarine

Comments:

2.4 Control Structures

2.4.1 if

The if statement enables us to execute code (or not) depending on a condition.

Here is an example:

>>> y = 25
>>>
>>> if y > 15:
...     print 'y is large'
... else:
...     print 'y is small'
...
y is large

A few notes:

2.4.2 for

The for statement enables us to iterate over collections. It enables us to repeat a set of lines of code once for each item in a collection. Collections are things like strings (arrays of characters), lists, tuples, and dictionaries.

Here is an example:

>>> collection = [111,222,333]
>>> for item in collection:
...     print 'item:', item
...
item: 111
item: 222
item: 333

Comments:

2.4.3 while

while is another repeating statement. It executes a block of code until a condition is false.

Here is an example:

>>> reply = 'repeat'
>>> while reply == 'repeat':
...     print 'Hello'
...     reply = raw_input('Enter "repeat" to do it again: ')
...
Hello
Enter "repeat" to do it again: repeat
Hello
Enter "repeat" to do it again: bye

Comments:

2.4.4 try-except and raise -- Exceptions

Use a try:except: block to catch an exception.

Use raise to raise an exception.

Comments and hints:

2.4.5 Reading Text Files

To read a text file, first create a file object. Here is an example:

inFile = file('messages.log', 'r')

Then use one or more of the file object's methods to process the contents of the file. Here are a few strategies:

2.4.6 Iterator objects

Note: You will need a sufficiently recent version of Python in order to use iterators and generators. I believe that they were introduced in Python 2.2.

Goals for this section:

Definitions:

A few additional basic points:

This section attempts to provide examples that illustrate the generator/iterator pattern.

Why is this important?

Examples - The remainder of this section provides a set of examples.

2.4.6.1 Example - A generator function

This function contains a yield statement. Therefore, when we call it, it produces an iterator.

def generateItems(seq):
    for item in seq:
        yield 'item: %s' % item

anIter = generateItems([])
print 'dir(anIter):', dir(anIter)
anIter = generateItems([111,222,333])
for x in anIter:
    print x
anIter = generateItems(['aaa', 'bbb', 'ccc'])
print anIter.next()
print anIter.next()
print anIter.next()
print anIter.next()

Running this example produces the following output:

dir(anIter): ['__class__', '__delattr__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__iter__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', 'gi_frame',
'gi_running', 'next']
item: 111
item: 222
item: 333
item: aaa
item: bbb
item: ccc
Traceback (most recent call last):
  File "iterator_generator.py", line 14, in ?
    print anIter.next()
StopIteration

Notes and explanation:

2.4.6.2 Example - A class containing a generator method

Each time this method is called, it produces a (new) iterator object. This method is analogous to the iterkeys and itervalues methods in the dictionary built-in object.

#
# A class that provides an iterator generator method.
#
class Node:
    def __init__(self, name='<noname>', value='<novalue>', children=None):
        self.name = name
        self.value = value
        self.children = children
        if children is None:
            self.children = []
        else:
            self.children = children
    def set_name(self, name): self.name = name
    def get_name(self): return self.name
    def set_value(self, value): self.value = value
    def get_value(self): return self.value
    def iterchildren(self):
        for child in self.children:
            yield child
    #
    # Print information on this node and walk over all children and
    #   grandchildren ...
    def walk(self, level=0):
        print '%sname: %s  value: %s' % (
            get_filler(level), self.get_name(), self.get_value(), )
        for child in self.iterchildren():
            child.walk(level + 1)

#
# An function that is the equivalent of the walk() method in
#   class Node.
#
def walk(node, level=0):
    print '%sname: %s  value: %s' % (
        get_filler(level), node.get_name(), node.get_value(), )
    for child in node.iterchildren():
        walk(child, level + 1)

def get_filler(level):
    return '    ' * level

def test():
    a7 = Node('gilbert', '777')
    a6 = Node('fred', '666')
    a5 = Node('ellie', '555')
    a4 = Node('daniel', '444')
    a3 = Node('carl', '333', [a4, a5])
    a2 = Node('bill', '222', [a6, a7])
    a1 = Node('alice', '111', [a2, a3])
    # Use the walk method to walk the entire tree.
    print 'Using the method:'
    a1.walk()
    print '=' * 30
    # Use the walk function to walk the entire tree.
    print 'Using the function:'
    walk(a1)

test()

Running this example produces the following output:

Using the method:
name: alice  value: 111
    name: bill  value: 222
        name: fred  value: 666
        name: gilbert  value: 777
    name: carl  value: 333
        name: daniel  value: 444
        name: ellie  value: 555
==============================
Using the function:
name: alice  value: 111
    name: bill  value: 222
        name: fred  value: 666
        name: gilbert  value: 777
    name: carl  value: 333
        name: daniel  value: 444
        name: ellie  value: 555

Notes and explanation:

2.4.6.3 Example - An iterator class

This class implements the iterator protocol. Therefore, instances of this class are iterators. The presence of the next and __iter__ methods means that this class implements the iterator protocol and makes instances of this class iterators.

Note that when an iterator is "exhausted" it, normally, cannot be reused to iterate over the sequence. However, in this example, we provide a refresh method which enables us to "rewind" and reuse the iterator instance.

#
# An iterator class that does *not* use ``yield``.
#   This iterator produces every other item in a sequence.
#
class IteratorExample:
    def __init__(self, seq):
        self.seq = seq
        self.idx = 0
    def next(self):
        self.idx += 1
        if self.idx >= len(self.seq):
            raise StopIteration
        value = self.seq[self.idx]
        self.idx += 1
        return value
    def __iter__(self):
        return self
    def refresh(self):
        self.idx = 0

def test_iteratorexample():
    a = IteratorExample('edcba')
    for x in a:
        print x
    print '----------'
    a.refresh()
    for x in a:
        print x
    print '=' * 30
    a = IteratorExample('abcde')
    try:
        print a.next()
        print a.next()
        print a.next()
        print a.next()
        print a.next()
        print a.next()
    except StopIteration, e:
        print 'stopping', e

Running this example produces the following output:

d
b
----------
d
b
==============================
b
d
stopping

Notes and explanation:

2.4.6.4 Example - An iterator class that uses yield

There may be times when the next method is easier and more straight-forward to implement using yield. If so, then this class might serve as an model. If you do not feel the need to do this, then you should ignore this example.

#
# An iterator class that uses ``yield``.
#   This iterator produces every other item in a sequence.
#
class YieldIteratorExample:
    def __init__(self, seq):
        self.seq = seq
        self.iterator = self._next()
        self.next = self.iterator.next
    def _next(self):
        flag = 0
        for x in self.seq:
            if flag:
                flag = 0
                yield x
            else:
                flag = 1
    def __iter__(self):
        return self.iterator
    def refresh(self):
        self.iterator = self._next()
        self.next = self.iterator.next

def test_yielditeratorexample():
    a = YieldIteratorExample('edcba')
    for x in a:
        print x
    print '----------'
    a.refresh()
    for x in a:
        print x
    print '=' * 30
    a = YieldIteratorExample('abcde')
    try:
        print a.next()
        print a.next()
        print a.next()
        print a.next()
        print a.next()
        print a.next()
    except StopIteration, e:
        print 'stopping', e

test_yielditeratorexample()

Running this example produces the following output:

d
b
----------
d
b
==============================
b
d
stopping

Notes and explanation:

2.4.6.5 Example - A list comprehension

A list comprehension looks a bit like an iterator, but it produces a list.

See 5.2.4 List displays for more on list comprehensions.

Here is an example:

In [4]: def f(x):
   ...:     return x * 3
   ...:
In [5]: list1 = [11, 22, 33]
In [6]: list2 = [f(x) for x in list1]
In [7]: print list2
[33, 66, 99]

2.4.6.6 Example - A generator expression

A generator expression looks quite similar to a list comprehension, but is enclosed in parentheses rather than square brackets. Unlike a list comprehension, a generator expression does not produce a list; it produces an iterator object.

For more on generator expressions, see 5.2.5 Generator expressions.

The following example uses a generator expression to produce an iterator.

mylist = range(10)

def f(x):
    return x*3

genexpr = (f(x) for x in mylist)

for x in genexpr:
    print x

Notes and explanation:

2.5 Organization

This section describes Python features that you can use to organize and structure your code.

2.5.1 Functions

2.5.1.1 A basic function

Use def to define a function. Here is a simple example:

def test(msg, count):
    for idx in range(count):
        print '%s %d' % (msg, idx)

test('Test #', 4)

Comments:

2.5.1.2 A function with default arguments

Providing default arguments allows the caller to omit some arguments. Here is an example:

def testDefaultArgs(arg1='default1', arg2='default2'):
    print 'arg1:', arg1
    print 'arg2:', arg2

testDefaultArgs('Explicit value')

The above example prints:

arg1: Explicit value
arg2: default2

2.5.1.3 Argument lists and keyword argument lists

Here is an example:

def testArgLists_1(*args, **kwargs):
    print 'args:', args
    print 'kwargs:', kwargs
            
testArgLists_1('aaa', 'bbb', arg1='ccc', arg2='ddd')

def testArgLists_2(arg0, *args, **kwargs):
    print 'arg0: "%s"' % arg0
    print 'args:', args
    print 'kwargs:', kwargs
            
print '=' * 40
testArgLists_2('a first argument', 'aaa', 'bbb', arg1='ccc', arg2='ddd')

Running this example displays:

args: ('aaa', 'bbb')
kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}
========================================
arg0: "a first argument"
args: ('aaa', 'bbb')
kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}

A little guidance:

2.5.2 Classes and Instances

2.5.2.1 A basic class

Define a basic class as follows:

class Basic:
    def __init__(self, name):
        self.name = name
    def show(self):
        print 'Basic -- name: %s' % self.name

obj1 = Basic('Apricot')
obj1.show()

Running the above example produces the following:

Basic -- name: Apricot

Explanation:

A few more notes on self:

2.5.2.2 Inheritance

Define a class Special that inherits from a super-class Basic as follows:

class Basic:
    def __init__(self, name):
        self.name = name
    def show(self):
        print 'Basic -- name: %s' % self.name

class Special(Basic):
    def __init__(self, name, edible):
        Basic.__init__(self, name)
        self.upper = name.upper()
        self.edible = edible
    def show(self):
        Basic.show(self)
        print 'Special -- upper name: %s.' % self.upper,
        if self.edible:
            print "It's edible."
        else:
            print "It's not edible."
    def edible(self):
        return self.edible

obj1 = Basic('Apricot')
obj1.show()
print '=' * 30
obj2 = Special('Peach', 1)
obj2.show()

Running this example produces the following:

Basic -- name: Apricot
==============================
Basic -- name: Peach
Special -- upper name: PEACH. It's edible.

Comments:

2.5.2.3 Class data

A class data member is a member that has only one value for the class and all its instances. Here is an example from the Python FAQ at http://www.python.org/doc/FAQ.html:

class C:
    count = 0   # number of times C.__init__ called
    def __init__(self):
        C.count = C.count + 1
    def getcount(self):
        return C.count  # or return self.count

c1 = C()
print 'Current count:', c1.getcount()
c2 = C()
print  'Current count:', c2.getcount()

Running this example produces:

Current count: 1
Current count: 2


2.5.2.4 Static methods and class methods

New-style classes can have static methods and class methods.

A new-style class is a class that inherits directly or indirectly from object or from a built-in type.

Here is an example that shows how to define static methods and class methods:

class Advanced(object):
    def __init__(self, name):
        self.name = name
    def Description():
        return 'This is an advanced class.'
    def ClassDescription(cls):
        return 'This is advanced class: %s' % repr(cls)
    Description = staticmethod(Description)
    ClassDescription = classmethod(ClassDescription)

obj1 = Advanced('Nectarine')
print obj1.Description()
print obj1.ClassDescription()
print '=' * 30
print Advanced.Description()
print  Advanced.ClassDescription()

Running the above produces the following output:

This is an advanced class.
This is advanced class: <class __main__.Advanced at 0x401c926c>
==============================
This is an advanced class.
This is advanced class: <class __main__.Advanced at 0x401c926c>

Notes:

You should also review the relevant standard Python documentation which you can find at Python Library Reference - 2.1 Built-in Functions.

By now, you are likely to be asking: "Why and when should I use class methods and static methods?" Here is a bit of guidance, though

To summarize:

2.5.2.5 Properties

A new-style class can have properties. A property is an attribute of a class that is associated with a getter and a setter function.

Declare the property and its getter and setter functions with property().

Here is an example:

class A(object):
    count = 0
    def __init__(self, name):
        self.name = name
    def set_name(self, name):
        print 'setting name: %s' % name
        self.name = name
    def get_name(self):
        print 'getting name: %s' % self.name
        return self.name
    objname = property(get_name, set_name)

def test():
    a = A('apple')
    print 'name: %s' % a.objname
    a.objname = 'banana'
    print 'name: %s' % a.objname

test()

Running the above produces the following output:

getting name: apple
name: apple
setting name: banana
getting name: banana
name: banana

Notes:

2.5.3 Modules

You can use a module to organize a number of Python definitions in a single file. Here is an example:

# python_101_module_simple.py

"""
This simple module contains definitions of a class and several 
functions.
"""

LABEL = '===== Testing a simple module ====='

class Person:
    """Sample of a simple class definition.
    """
    def __init__(self, name, description):
        self.name = name
        self.description = description
    def show(self):
        print 'Person -- name: %s  description: %s' % (self.name, self.description)

def test(msg, count):
    """A sample of a simple function.
    """
    for idx in range(count):
        print '%s %d' % (msg, idx)

def testDefaultArgs(arg1='default1', arg2='default2'):
    """A function with default arguments.
    """
    print 'arg1:', arg1
    print 'arg2:', arg2

def testArgLists(*args, **kwargs):
    """
    A function which references the argument list and keyword arguments.
    """
    print 'args:', args
    print 'kwargs:', kwargs

def main():
    """
    A test harness for this module.
    """
    print LABEL
    person = Person('Herman', 'A cute guy')
    person.show()
    print '=' * 30
    test('Test #', 4)
    print '=' * 30
    testDefaultArgs('Explicit value')
    print '=' * 30
    testArgLists('aaa', 'bbb', arg1='ccc', arg2='ddd')

if __name__ == '__main__':
    main()

Running the above produces the following output:

===== Testing a simple module =====
Person -- name: Herman  description: A cute guy
==============================
Test # 0
Test # 1
Test # 2
Test # 3
==============================
arg1: Explicit value
arg2: default2
==============================
args: ('aaa', 'bbb')
kwargs: {'arg1': 'ccc', 'arg2': 'ddd'}

Comments:

2.5.4 Packages

A package is a way to organize a number of modules together as a unit. Python packages can also contain other packages.

To give us an example to talk about, consider the follow package structure:

package_example/
package_example/__init__.py
package_example/module1.py
package_example/module2.py
package_example/A.py
package_example/B.py

And, here are the contents:

# __init__.py

# Expose definitions from modules in this package.
from module1 import class1
from module2 import class2
# module1.py

class class1:
    def __init__(self):
        self.description = 'class #1'
    def show(self):
        print self.description
# module2.py

class class2:
    def __init__(self):
        self.description = 'class #2'
    def show(self):
        print self.description
# A.py

import B
# B.py

def function_b():
    print 'Hello from function_b'

In order to be used as a Python package (e.g. so that modules can be imported from it) a directory must contain a file whose name is __init__.py. The code in this module is evaluated the first time a module is imported from the package.

In order to import modules from a package, you may either add the package directory to sys.path or, if the parent directory is on sys.path, use dot-notation to explicitly specify the path. In our example, you might use: "import package_example.module1".

A module in a package can import another module from the same package directly without using the path to the package. For example, the module A in our sample package package_example can import module B in the same package with "import B". Module A does not need to use "import package_example.B".

You can find additional information on packages at http://www.python.org/doc/essays/packages.html.

Suggested techniques:

A few additional notes:


End Matter

Acknowledgements and Thanks

Thanks to the implementors of Python for producing an exceptionally usable and enjoyable programming language.

See Also:

The main Python Web Site
for more information on Python

Python Documentation
for lots of documentation on Python

The Python XML Special Interest Group
for more information on processing XML with Python

Dave's Web Site
for more software and information on using Python for XML and the Web

About this document ...

Python 101 -- Introduction to Python, August 7, 2008, Release 1.01

This document was generated using the LaTeX2HTML translator.

LaTeX2HTML is Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds, and Copyright © 1997, 1998, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The application of LaTeX2HTML to the Python documentation has been heavily tailored by Fred L. Drake, Jr. Original navigation icons were contributed by Christopher Petrilli.