home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Unix Power ToolsUnix Power ToolsSearch this book

42.3. Python Basics

If you've written code in a procedural or functional language before, many parts of Python will seem familiar. Here's a quick overview of the flavor of the language. There is a lot of both reference and tutorial information available on the web (start at http://www.python.org) as well as in books like O'Reilly's Programming Python. In fact, much of the information in this chapter was gleaned or paraphrased from the official Python reference documentation.

42.3.2. Functions

Both procedural and functional languages organize programs by dividing them into smaller units called functions. Python's approach to functions is inspired by functional languages like Lisp and Scheme, where anonymous functions (lambdas) and operations like eval, apply, map, and reduce are fundamentals of the language.

Functions are defined with the def statement. To define an add function that adds together two arguments and returns the result:

>>> def add(a, b):
...     return a + b

This defines a function and attaches it to the name add in the current namespace; anything with access to this namespace can call this function by simply passing arguments to it:

>>> print add(3, 5)
8

Function arguments can be defined with default values, and variable-length argument lists and keyword arguments are also supported.

Procedural programming languages like Perl and C generally leave functions at that. Functional languages like Lisp, Scheme, and Python take functions to the next level; functions are first-class objects and can be directly manipulated and stored.

Anonymous functions, which are not automatically attached to the current namespace, are created with the lambda statement:

>>> add = lambda a, b: a + b

Lambdas are very useful for traditional functional programming tricks such as using map( ). map( ) takes its first argument (which should be a function or lambda) and runs it over and over, passing each element of the list to the function in turn, generating a new list of the results:

>>> def timesThree(a):
...     return 3 * a
>>> def sum(x, y):
...     return x + y

>>> ints = [1, 2, 3, 4, 5]
>>> multiples = map(timesThree, ints)
>>> print multiples
[3, 6, 9, 12, 15]
>>> print reduce(sum, multiples)
45

If you use functions like map( ) and its cousins apply( ), reduce( ), and filter( ) a lot, your code can get pretty messy before long. Using a lambda allows you to use these functions without having to define a named function with def; instead you can just put the lambda right into the function call as an argument:

>>> ints = [1, 2, 3, 4, 5]
>>> multiples = map(lambda a: 3 * a, ints)
>>> print multiples
[3, 6, 9, 12, 15]
>>> print reduce(lambda x, y: x + y, multiples)
45

Lambdas are limited to a single expression, though that expression may be complex. Multiple statements and nonexpression statements like print and while can't be used in a lambda.

42.3.3. Everything's an Object

Everything in Python is an object. Each object has an identity , a type, and a value. For example, a = 42 creates an object of type integer with the value 42. You can think of the identity of an object as its address in memory; in this case, we've given the name a to that identity. Python's built-in types include fundamental building blocks such as numbers, strings, lists, dictionaries, and files, as well as structuring types like functions, modules, lambdas, and metaclasses. (Yes, a function is an object; it's just an object that implements the "function call" operator.)

Python allows the creation of new types of objects via the class statement. User-defined classes can have class variables and methods, which are shared across all instances of that class. In Python, methods are just functions that happen to be associated with a class (and generally take an instance of that class as the first argument). Instances can also have their own instance variables, specific to each instance.

Instances are created by calling the class object as if it were a function, which creates a new object and calls the _ _init_ _( ) method of the class (if one is defined):

class Account:
    "A simple example class"
    kind = "Checking"
    def _ _init_ _(self, accountHolder, startingBalance):
        self.accountHolder = accountHolder;
        self.balance = startingBalance;

>>> account = Account("Deb", 86753.09)

This creates a new Account object and sets the accountHolder instance variable to Deb and the balance instance variable to $86,753.09. Now, in order to be able to do anything with our Account, we need to define methods to allow manipulation of the balance:

class Account:
    ...
    def deposit(self, depositAmount):
        "Deposit money"
        self.balance = self.balance + depositAmount
    def withdraw(self, withdrawalAmount):
        "Withdraw money"
        self.balance = self.balance - withdrawalAmount
    def inquireBalance(self):
        "Balance inquiry"
        return self.balance

>>> account.deposit(1504.36)
>>> account.withdraw(40.00)
>>> print "Account balance is now $%.2f" % account.inquireBalance( )
Account balance is now $88217.45

42.3.4. Modules and Packages

Modules and packages allow you to organize your code more effectively. Generally, software for Python is also distributed as a module or a package. A module groups a set of functions and classes; a package is a collection of modules and subpackages.

Any Python source file is a module, if you load it using the import statement. Importing a module creates an isolated namespace for the symbols within that file and attaches that namespace to the name of the module. It also executes the code within that module, defining variables, functions, and classes. For example, we might put our Account class in a file account.py, and then, in another file:

import account

checking = account.Account("Deb", 86753.09)

Note that we can't refer to Account directly; we have to refer to it through its imported name, account.Account. If, for convenience, we'd like to access the Account class directly, we can tell Python to import the class into our current namespace as well:

from account import Account

checking = Account("Deb", 86753.09)

Modules are compiled into bytecodes the first time they are imported, allowing them to run faster and be more compact.

Given that a Python module is just a file, it will probably come as no surprise that a Python package is simply a directory with modules in it. To tag a directory as a package rather than just any directory, create a file called _ _init_ _.py (the same name as the method to initialize an object) within that directory. Code within _ _init_ _.py will get run whenever any part of its package is imported. Subpackages are, of course, just subdirectories with their own _ _init_ _.py files.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.