Python has many features that usually are found only in languages which are much more complex to learn and use. These features were designed into python from its very first beginnings, rather than being accumulated into an end result, as is the case with many other scripting languages. If you’re new to programming, even the basic descriptions which follow may seem intimidating. But don’t worry – all of these ideas will be made clearer in the chapters which follow. The idea of presenting these concepts now is to make you aware of how python works, and the general philosophy behind python programming. If some of the concepts that are introduced here seem
abstract or overly complex, just try to get a general feel for the idea, and the details will be fleshed out later.
abstract or overly complex, just try to get a general feel for the idea, and the details will be fleshed out later.
Basic Core Language
Python is designed so that there really isn’t that much to learn in the basic
language. For example, there is only one basic structure for conditional programming (if/else/elif), two looping commands (while and for), and a consistent method of handling errors (try/except) which apply to all python
programs. This doesn’t mean that the language is not flexible and powerful,
however. It simply means that you’re not confronted with an overwhelming
choice of options at every turn, which can make programming a much simpler task.
Modules
Python relies on modules, that is, self-contained programs which define a
variety of functions and data types, that you can call in order to do tasks be-
yond the scope of the basic core language by using the import command. For
example, the core distribution of python contains modules for processing files,
accessing your computer’s operating system and the internet, writing CGI
scripts (which handle communicating with pages displayed in web browsers),
string handling and many other tasks. Optional modules, available on the
Python web site (http://www.python.org), can be used to create graphical
user interfaces, communicate with data bases, process image files, and so on.
This structure makes it easy to get started with python, learning specific
skills only as you need them, as well as making python run more efficiently
by not always including every capability in every program.
Object Oriented Programming
Python is a true object-oriented language. The term “object oriented” has become quite a popular buzzword; such high profile languages as C++ and Java are both object oriented by design. Many other languages add some object-oriented capabilities, but were not designed to be object oriented from the ground up as python was. Why is this feature important? Object oriented program allows you to focus on the data you’re interested in, whether it’s employee information, the results of a scientific experiment or survey, setlists for your favorite band, the contents of your CD collection, information entered by an internet user into a search form or shopping cart, and to develop methods to deal efficiently with your data. A basic concept of object oriented programming is encapsulation, the ability to define an object that contains your data and all the information a program needs to operate
on that data. In this way, when you call a function (known as a method in object-oriented lingo), you don’t need to specify a lot of details about your data, because your data object “knows” all about itself. In addition, objects can inherit from other objects, so if you or someone else has designed an object that’s very close to one you’re interested in, you only have to construct those methods which differ from the existing object, allowing you to save a lot of work.Another nice feature of object oriented programs is operator overloading.What this means is that the same operator can have different meanings when used with different types of data. For example, in python, when you’re
dealing with numbers, the plus sign (+) has its usual obvious meaning of addition. But when you’re dealing with strings, the plus sign means to join the two strings together. In addition to being able to use overloading for built-in types (like numbers and strings), python also allows you to define
what operators mean for the data types you create yourself.Perhaps the nicest feature of object-oriented programming in python is that you can use as much or as little of it as you want. Until you get comfortable with the ideas behind object-oriented programming, you can write more traditional programs in python without any problems.
Namespaces and Variable Scoping
When you type the name of a variable inside a script or interactive python
session, python needs to figure out exactly what variable you’re using. To prevent variables you create from overwriting or interfering with variables in python itself or in the modules you use, python uses the concept of multiple namespaces. Basically, this means that the same variable name can be used in different parts of a program without fear of destroying the value of a variable you’re not concerned with.
To keep its bookkeeping in order, python enforces what is known as the LGB rule. First, the local namespace is searched, then the global namespace, then the namespace of python built-in functions and variables. A local namespace is automatically created whenever you write a function, or a module containing any of functions, class definitions, or methods. The global namespace consists primarily of the variables you create as part of the “toplevel” program, like a script or an interactive session. Finally, the built-in namespace consists of the objects which are part of python’s core. You can see the contents of any of the namespaces by using the dir command:
>>> dir()
[’__builtins__’, ’__doc__’, ’__name__’]
>>> dir(__builtins__)
[’ArithmeticError’, ’AssertionError’, ’AttributeError’, ’EOFError’,
’Ellipsis’, ’Exception’, ’FloatingPointError’, ’IOError’, ’ImportError’,
’IndexError’, ’KeyError’, ’KeyboardInterrupt’, ’LookupError’,
’MemoryError’, ’NameError’, ’None’, ’OverflowError’, ’RuntimeError’,
’StandardError’, ’SyntaxError’, ’SystemError’, ’SystemExit’, ’TypeError’,
’ValueError’, ’ZeroDivisionError’, ’_’, ’__debug__’, ’__doc__’,’__import__’, ’__name__’, ’abs’, ’apply’, ’callable’, ’chr’, ’cmp’, ’coerce’, ’compile’, ’complex’, ’delattr’, ’dir’, ’divmod’, ’eval’, ’execfile’, ’filter’, ’float’, ’getattr’, ’globals’, ’hasattr’, ’hash’, ’hex’, ’id’, ’input’, ’int’, ’intern’, ’isinstance’,
’issubclass’, ’len’, ’list’, ’locals’, ’long’, ’map’, ’max’, ’min’, ’oct’, ’open’, ’ord’, ’pow’, ’range’, ’raw_input’, ’reduce’, ’reload’,
’repr’, ’round’, ’setattr’, ’slice’, ’str’, ’tuple’, ’type’, ’vars’, ’xrange’]
The __builtins__ namespace contains all the functions, variables and exceptions which are part of python’s core.To give controlled access to other namespaces, python uses the import statement. There are three ways to use this statement. In its simplest form,
you import the name of a module; this allows you to specify the various objects defined in that module by using a two level name, with the module’s name and the object’s name separated by a period. For example, the string module provides many functions useful for dealing with character strings. Suppose we want to use the split function of the string module to break up a sentence into a list containing separate words. We could use the following sequence of statements:
>>> import string
>>> string.split(’Welcome to the Ministry of Silly Walks’)
[’Welcome’, ’to’, ’the’, ’Ministry’, ’of’, ’Silly’, ’Walks’]
If we had tried to refer to this function as simply “split”, python would not
be able to find it. That’s because we have only imported the string module
into the local namespace, not all of the objects defined in the module. (See
below for details of how to do that.) The second form of the import statement is more specific; it specifies the individual objects from a module whose names we want imported into the local namespace. For example, if we only needed the two functions split and join for use in a program, we could import just those two names directly into the local namespace, allowing us to dispense with the string. prefix:
>>> from string import split,join
>>> split(’Welcome to the Ministry of Silly Walks’) [’Welcome’, ’to’, ’the’, ’Ministry’, ’of’, ’Silly’, ’Walks’]
This technique reduces the amount of typing we need to do, and is an efficient
way to bring just a few outside objects into the local environment.
Finally, some modules are designed so that you’re expected to have top level access to all of the functions in the module without having to use the module name as a prefix. In cases like this you can use a statement like:
>>> from string import *
Now all of the objects defined in the string module are available directly in the top-level environment, with no need for a prefix. You should use this technique with caution, because certain commonly used names from the module may override the names of your variables. In addition, it introduces lots of names into the local namespace, which could adversely affect python’s efficiency.
Exception Handling
Regardless how carefully you write your programs, when you start using them in a variety of situations, errors are bound to occur. Python provides a consistent method of handling errors, a topic often refered to as exception handling. When you’re performing an operation that might result in an error, you can surround it with a try loop, and provide an except clause to tell python what to do when a particular error arises. While this is a fairly advanced concept, usually found in more complex languages, you can start using it in even your earliest python programs.
As a simple example, consider dividing two numbers. If the divisor is zero, most programs (python included) will stop running, leaving the userback at a system shell prompt, or with nothing at all. Here’s a little python program that illustrates this concept; assume we’ve saved it to a file called div.py:
#!/usr/local/bin/python
x = 7
y = 0
print x/y
print "Now we’re done!"
When we run this program, we don’t get to the line which prints the message,
because the division by zero is a “fatal” error:
% div.py
Traceback (innermost last):
File "div.py", line 5, in ?
print x/y
ZeroDivisionError: integer division or modulo
While the message may look a little complicated, the main point to notice
is that the last line of the message tells us the name of the exception that
occured. This allows us to construct an except clause to handle the problem:
x = 7
y = 0
try:
print x/y
except ZeroDivisionError:
print "Oops - I can’t divide by zero, sorry!"
Now when we run the program, it behaves a little more nicely:
% div.py
Oops - I can’t divide by zero, sorry!
Now we’re done!
Since each exception in python has a name, it’s very easy to modify your
program to handle errors whenever they’re discovered. And of course, if you
can think ahead, you can construct try/except clauses to catch errors before they happen.
0 Comments