:tocdepth: 2

=========================
Library and Extension FAQ
=========================

.. only:: html

   .. contents::

General Library Questions
=========================

How do I find a module or application to perform task X?
--------------------------------------------------------

Check :ref:`the Library Reference <library-index>` to see if there's a relevant
standard library module.  (Eventually you'll learn what's in the standard
library and will be able to skip this step.)

For third-party packages, search the `Python Package Index
<http://pypi.python.org/pypi>`_ or try `Google <http://www.google.com>`_ or
another Web search engine.  Searching for "Python" plus a keyword or two for
your topic of interest will usually find something helpful.


Where is the math.py (socket.py, regex.py, etc.) source file?
-------------------------------------------------------------

If you can't find a source file for a module it may be a built-in or
dynamically loaded module implemented in C, C++ or other compiled language.
In this case you may not have the source file or it may be something like
:file:`mathmodule.c`, somewhere in a C source directory (not on the Python Path).

There are (at least) three kinds of modules in Python:

1) modules written in Python (.py);
2) modules written in C and dynamically loaded (.dll, .pyd, .so, .sl, etc);
3) modules written in C and linked with the interpreter; to get a list of these,
   type::

      import sys
      print(sys.builtin_module_names)


How do I make a Python script executable on Unix?
-------------------------------------------------

You need to do two things: the script file's mode must be executable and the
first line must begin with ``#!`` followed by the path of the Python
interpreter.

The first is done by executing ``chmod +x scriptfile`` or perhaps ``chmod 755
scriptfile``.

The second can be done in a number of ways.  The most straightforward way is to
write ::

  #!/usr/local/bin/python

as the very first line of your file, using the pathname for where the Python
interpreter is installed on your platform.

If you would like the script to be independent of where the Python interpreter
lives, you can use the :program:`env` program.  Almost all Unix variants support
the following, assuming the Python interpreter is in a directory on the user's
:envvar:`PATH`::

  #!/usr/bin/env python

*Don't* do this for CGI scripts.  The :envvar:`PATH` variable for CGI scripts is
often very minimal, so you need to use the actual absolute pathname of the
interpreter.

Occasionally, a user's environment is so full that the :program:`/usr/bin/env`
program fails; or there's no env program at all.  In that case, you can try the
following hack (due to Alex Rezinsky)::

   #! /bin/sh
   """:"
   exec python $0 ${1+"$@"}
   """

The minor disadvantage is that this defines the script's __doc__ string.
However, you can fix that by adding ::

   __doc__ = """...Whatever..."""



Is there a curses/termcap package for Python?
---------------------------------------------

.. XXX curses *is* built by default, isn't it?

For Unix variants: The standard Python source distribution comes with a curses
module in the :source:`Modules` subdirectory, though it's not compiled by default.
(Note that this is not available in the Windows distribution -- there is no
curses module for Windows.)

The :mod:`curses` module supports basic curses features as well as many additional
functions from ncurses and SYSV curses such as colour, alternative character set
support, pads, and mouse support. This means the module isn't compatible with
operating systems that only have BSD curses, but there don't seem to be any
currently maintained OSes that fall into this category.

For Windows: use `the consolelib module
<http://effbot.org/zone/console-index.htm>`_.


Is there an equivalent to C's onexit() in Python?
-------------------------------------------------

The :mod:`atexit` module provides a register function that is similar to C's
:c:func:`onexit`.


Why don't my signal handlers work?
----------------------------------

The most common problem is that the signal handler is declared with the wrong
argument list.  It is called as ::

   handler(signum, frame)

so it should be declared with two arguments::

   def handler(signum, frame):
       ...


Common tasks
============

How do I test a Python program or component?
--------------------------------------------

Python comes with two testing frameworks.  The :mod:`doctest` module finds
examples in the docstrings for a module and runs them, comparing the output with
the expected output given in the docstring.

The :mod:`unittest` module is a fancier testing framework modelled on Java and
Smalltalk testing frameworks.

To make testing easier, you should use good modular design in your program.
Your program should have almost all functionality
encapsulated in either functions or class methods -- and this sometimes has the
surprising and delightful effect of making the program run faster (because local
variable accesses are faster than global accesses).  Furthermore the program
should avoid depending on mutating global variables, since this makes testing
much more difficult to do.

The "global main logic" of your program may be as simple as ::

   if __name__ == "__main__":
       main_logic()

at the bottom of the main module of your program.

Once your program is organized as a tractable collection of functions and class
behaviours you should write test functions that exercise the behaviours.  A test
suite that automates a sequence of tests can be associated with each module.
This sounds like a lot of work, but since Python is so terse and flexible it's
surprisingly easy.  You can make coding much more pleasant and fun by writing
your test functions in parallel with the "production code", since this makes it
easy to find bugs and even design flaws earlier.

"Support modules" that are not intended to be the main module of a program may
include a self-test of the module. ::

   if __name__ == "__main__":
       self_test()

Even programs that interact with complex external interfaces may be tested when
the external interfaces are unavailable by using "fake" interfaces implemented
in Python.


How do I create documentation from doc strings?
-----------------------------------------------

The :mod:`pydoc` module can create HTML from the doc strings in your Python
source code.  An alternative for creating API documentation purely from
docstrings is `epydoc <http://epydoc.sf.net/>`_.  `Sphinx
<http://sphinx.pocoo.org>`_ can also include docstring content.


How do I get a single keypress at a time?
-----------------------------------------

For Unix variants there are several solutions.  It's straightforward to do this
using curses, but curses is a fairly large module to learn.

.. XXX this doesn't work out of the box, some IO expert needs to check why

   Here's a solution without curses::

   import termios, fcntl, sys, os
   fd = sys.stdin.fileno()

   oldterm = termios.tcgetattr(fd)
   newattr = termios.tcgetattr(fd)
   newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
   termios.tcsetattr(fd, termios.TCSANOW, newattr)

   oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
   fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

   try:
       while True:
           try:
               c = sys.stdin.read(1)
               print("Got character", repr(c))
           except OSError:
               pass
   finally:
       termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
       fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

   You need the :mod:`termios` and the :mod:`fcntl` module for any of this to
   work, and I've only tried it on Linux, though it should work elsewhere.  In
   this code, characters are read and printed one at a time.

   :func:`termios.tcsetattr` turns off stdin's echoing and disables canonical
   mode.  :func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags
   and modify them for non-blocking mode.  Since reading stdin when it is empty
   results in an :exc:`OSError`, this error is caught and ignored.

   .. versionchanged:: 3.3
      *sys.stdin.read* used to raise :exc:`IOError`. Starting from Python 3.3
      :exc:`IOError` is alias for :exc:`OSError`.


Threads
=======

How do I program using threads?
-------------------------------

Be sure to use the :mod:`threading` module and not the :mod:`_thread` module.
The :mod:`threading` module builds convenient abstractions on top of the
low-level primitives provided by the :mod:`_thread` module.

Aahz has a set of slides from his threading tutorial that are helpful; see
http://www.pythoncraft.com/OSCON2001/.


None of my threads seem to run: why?
------------------------------------

As soon as the main thread exits, all threads are killed.  Your main thread is
running too quickly, giving the threads no time to do any work.

A simple fix is to add a sleep to the end of the program that's long enough for
all the threads to finish::

   import threading, time

   def thread_task(name, n):
       for i in range(n): print(name, i)

   for i in range(10):
       T = threading.Thread(target=thread_task, args=(str(i), i))
       T.start()

   time.sleep(10)  # <---------------------------!

But now (on many platforms) the threads don't run in parallel, but appear to run
sequentially, one at a time!  The reason is that the OS thread scheduler doesn't
start a new thread until the previous thread is blocked.

A simple fix is to add a tiny sleep to the start of the run function::

   def thread_task(name, n):
       time.sleep(0.001)  # <--------------------!
       for i in range(n): print(name, i)

   for i in range(10):
       T = threading.Thread(target=thread_task, args=(str(i), i))
       T.start()

   time.sleep(10)

Instead of trying to guess a good delay value for :func:`time.sleep`,
it's better to use some kind of semaphore mechanism.  One idea is to use the
:mod:`queue` module to create a queue object, let each thread append a token to
the queue when it finishes, and let the main thread read as many tokens from the
queue as there are threads.


How do I parcel out work among a bunch of worker threads?
---------------------------------------------------------

The easiest way is to use the new :mod:`concurrent.futures` module,
especially the :mod:`~concurrent.futures.ThreadPoolExecutor` class.

Or, if you want fine control over the dispatching algorithm, you can write
your own logic manually.  Use the :mod:`queue` module to create a queue
containing a list of jobs.  The :class:`~queue.Queue` class maintains a
list of objects and has a ``.put(obj)`` method that adds items to the queue and
a ``.get()`` method to return them.  The class will take care of the locking
necessary to ensure that each job is handed out exactly once.

Here's a trivial example::

   import threading, queue, time

   # The worker thread gets jobs off the queue.  When the queue is empty, it
   # assumes there will be no more work and exits.
   # (Realistically workers will run until terminated.)
   def worker():
       print('Running worker')
       time.sleep(0.1)
       while True:
           try:
               arg = q.get(block=False)
           except queue.Empty:
               print('Worker', threading.currentThread(), end=' ')
               print('queue empty')
               break
           else:
               print('Worker', threading.currentThread(), end=' ')
               print('running with argument', arg)
               time.sleep(0.5)

   # Create queue
   q = queue.Queue()

   # Start a pool of 5 workers
   for i in range(5):
       t = threading.Thread(target=worker, name='worker %i' % (i+1))
       t.start()

   # Begin adding work to the queue
   for i in range(50):
       q.put(i)

   # Give threads time to run
   print('Main thread sleeping')
   time.sleep(5)

When run, this will produce the following output:

.. code-block:: none

   Running worker
   Running worker
   Running worker
   Running worker
   Running worker
   Main thread sleeping
   Worker <Thread(worker 1, started 130283832797456)> running with argument 0
   Worker <Thread(worker 2, started 130283824404752)> running with argument 1
   Worker <Thread(worker 3, started 130283816012048)> running with argument 2
   Worker <Thread(worker 4, started 130283807619344)> running with argument 3
   Worker <Thread(worker 5, started 130283799226640)> running with argument 4
   Worker <Thread(worker 1, started 130283832797456)> running with argument 5
   ...

Consult the module's documentation for more details; the :class:`~queue.Queue`
class provides a featureful interface.


What kinds of global value mutation are thread-safe?
----------------------------------------------------

A :term:`global interpreter lock` (GIL) is used internally to ensure that only one
thread runs in the Python VM at a time.  In general, Python offers to switch
among threads only between bytecode instructions; how frequently it switches can
be set via :func:`sys.setswitchinterval`.  Each bytecode instruction and
therefore all the C implementation code reached from each instruction is
therefore atomic from the point of view of a Python program.

In theory, this means an exact accounting requires an exact understanding of the
PVM bytecode implementation.  In practice, it means that operations on shared
variables of built-in data types (ints, lists, dicts, etc) that "look atomic"
really are.

For example, the following operations are all atomic (L, L1, L2 are lists, D,
D1, D2 are dicts, x, y are objects, i, j are ints)::

   L.append(x)
   L1.extend(L2)
   x = L[i]
   x = L.pop()
   L1[i:j] = L2
   L.sort()
   x = y
   x.field = y
   D[x] = y
   D1.update(D2)
   D.keys()

These aren't::

   i = i+1
   L.append(L[-1])
   L[i] = L[j]
   D[x] = D[x] + 1

Operations that replace other objects may invoke those other objects'
:meth:`__del__` method when their reference count reaches zero, and that can
affect things.  This is especially true for the mass updates to dictionaries and
lists.  When in doubt, use a mutex!


Can't we get rid of the Global Interpreter Lock?
------------------------------------------------

.. XXX link to dbeazley's talk about GIL?

The :term:`global interpreter lock` (GIL) is often seen as a hindrance to Python's
deployment on high-end multiprocessor server machines, because a multi-threaded
Python program effectively only uses one CPU, due to the insistence that
(almost) all Python code can only run while the GIL is held.

Back in the days of Python 1.5, Greg Stein actually implemented a comprehensive
patch set (the "free threading" patches) that removed the GIL and replaced it
with fine-grained locking.  Adam Olsen recently did a similar experiment
in his `python-safethread <http://code.google.com/p/python-safethread/>`_
project.  Unfortunately, both experiments exhibited a sharp drop in single-thread
performance (at least 30% slower), due to the amount of fine-grained locking
necessary to compensate for the removal of the GIL.

This doesn't mean that you can't make good use of Python on multi-CPU machines!
You just have to be creative with dividing the work up between multiple
*processes* rather than multiple *threads*.  The
:class:`~concurrent.futures.ProcessPoolExecutor` class in the new
:mod:`concurrent.futures` module provides an easy way of doing so; the
:mod:`multiprocessing` module provides a lower-level API in case you want
more control over dispatching of tasks.

Judicious use of C extensions will also help; if you use a C extension to
perform a time-consuming task, the extension can release the GIL while the
thread of execution is in the C code and allow other threads to get some work
done.  Some standard library modules such as :mod:`zlib` and :mod:`hashlib`
already do this.

It has been suggested that the GIL should be a per-interpreter-state lock rather
than truly global; interpreters then wouldn't be able to share objects.
Unfortunately, this isn't likely to happen either.  It would be a tremendous
amount of work, because many object implementations currently have global state.
For example, small integers and short strings are cached; these caches would
have to be moved to the interpreter state.  Other object types have their own
free list; these free lists would have to be moved to the interpreter state.
And so on.

And I doubt that it can even be done in finite time, because the same problem
exists for 3rd party extensions.  It is likely that 3rd party extensions are
being written at a faster rate than you can convert them to store all their
global state in the interpreter state.

And finally, once you have multiple interpreters not sharing any state, what
have you gained over running each interpreter in a separate process?


Input and Output
================

How do I delete a file? (And other file questions...)
-----------------------------------------------------

Use ``os.remove(filename)`` or ``os.unlink(filename)``; for documentation, see
the :mod:`os` module.  The two functions are identical; :func:`~os.unlink` is simply
the name of the Unix system call for this function.

To remove a directory, use :func:`os.rmdir`; use :func:`os.mkdir` to create one.
``os.makedirs(path)`` will create any intermediate directories in ``path`` that
don't exist. ``os.removedirs(path)`` will remove intermediate directories as
long as they're empty; if you want to delete an entire directory tree and its
contents, use :func:`shutil.rmtree`.

To rename a file, use ``os.rename(old_path, new_path)``.

To truncate a file, open it using ``f = open(filename, "rb+")``, and use
``f.truncate(offset)``; offset defaults to the current seek position.  There's
also ``os.ftruncate(fd, offset)`` for files opened with :func:`os.open`, where
*fd* is the file descriptor (a small integer).

The :mod:`shutil` module also contains a number of functions to work on files
including :func:`~shutil.copyfile`, :func:`~shutil.copytree`, and
:func:`~shutil.rmtree`.


How do I copy a file?
---------------------

The :mod:`shutil` module contains a :func:`~shutil.copyfile` function.  Note
that on MacOS 9 it doesn't copy the resource fork and Finder info.


How do I read (or write) binary data?
-------------------------------------

To read or write complex binary data formats, it's best to use the :mod:`struct`
module.  It allows you to take a string containing binary data (usually numbers)
and convert it to Python objects; and vice versa.

For example, the following code reads two 2-byte integers and one 4-byte integer
in big-endian format from a file::

   import struct

   with open(filename, "rb") as f:
      s = f.read(8)
      x, y, z = struct.unpack(">hhl", s)

The '>' in the format string forces big-endian data; the letter 'h' reads one
"short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the
string.

For data that is more regular (e.g. a homogeneous list of ints or floats),
you can also use the :mod:`array` module.

.. note::
   To read and write binary data, it is mandatory to open the file in
   binary mode (here, passing ``"rb"`` to :func:`open`).  If you use
   ``"r"`` instead (the default), the file will be open in text mode
   and ``f.read()`` will return :class:`str` objects rather than
   :class:`bytes` objects.


I can't seem to use os.read() on a pipe created with os.popen(); why?
---------------------------------------------------------------------

:func:`os.read` is a low-level function which takes a file descriptor, a small
integer representing the opened file.  :func:`os.popen` creates a high-level
file object, the same type returned by the built-in :func:`open` function.
Thus, to read *n* bytes from a pipe *p* created with :func:`os.popen`, you need to
use ``p.read(n)``.


.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section.

   How do I run a subprocess with pipes connected to both input and output?
   ------------------------------------------------------------------------

   Use the :mod:`popen2` module.  For example::

      import popen2
      fromchild, tochild = popen2.popen2("command")
      tochild.write("input\n")
      tochild.flush()
      output = fromchild.readline()

   Warning: in general it is unwise to do this because you can easily cause a
   deadlock where your process is blocked waiting for output from the child
   while the child is blocked waiting for input from you.  This can be caused
   by the parent expecting the child to output more text than it does or
   by data being stuck in stdio buffers due to lack of flushing.
   The Python parent can of course explicitly flush the data it sends to the
   child before it reads any output, but if the child is a naive C program it
   may have been written to never explicitly flush its output, even if it is
   interactive, since flushing is normally automatic.

   Note that a deadlock is also possible if you use :func:`popen3` to read
   stdout and stderr. If one of the two is too large for the internal buffer
   (increasing the buffer size does not help) and you ``read()`` the other one
   first, there is a deadlock, too.

   Note on a bug in popen2: unless your program calls ``wait()`` or
   ``waitpid()``, finished child processes are never removed, and eventually
   calls to popen2 will fail because of a limit on the number of child
   processes.  Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can
   prevent this; a good place to insert such a call would be before calling
   ``popen2`` again.

   In many cases, all you really need is to run some data through a command and
   get the result back.  Unless the amount of data is very large, the easiest
   way to do this is to write it to a temporary file and run the command with
   that temporary file as input.  The standard module :mod:`tempfile` exports a
   :func:`~tempfile.mktemp` function to generate unique temporary file names. ::

      import tempfile
      import os

      class Popen3:
          """
          This is a deadlock-safe version of popen that returns
          an object with errorlevel, out (a string) and err (a string).
          (capturestderr may not work under windows.)
          Example: print(Popen3('grep spam','\n\nhere spam\n\n').out)
          """
          def __init__(self,command,input=None,capturestderr=None):
              outfile=tempfile.mktemp()
              command="( %s ) > %s" % (command,outfile)
              if input:
                  infile=tempfile.mktemp()
                  open(infile,"w").write(input)
                  command=command+" <"+infile
              if capturestderr:
                  errfile=tempfile.mktemp()
                  command=command+" 2>"+errfile
              self.errorlevel=os.system(command) >> 8
              self.out=open(outfile,"r").read()
              os.remove(outfile)
              if input:
                  os.remove(infile)
              if capturestderr:
                  self.err=open(errfile,"r").read()
                  os.remove(errfile)

   Note that many interactive programs (e.g. vi) don't work well with pipes
   substituted for standard input and output.  You will have to use pseudo ttys
   ("ptys") instead of pipes. Or you can use a Python interface to Don Libes'
   "expect" library.  A Python extension that interfaces to expect is called
   "expy" and available from http://expectpy.sourceforge.net.  A pure Python
   solution that works like expect is `pexpect
   <http://pypi.python.org/pypi/pexpect/>`_.


How do I access the serial (RS232) port?
----------------------------------------

For Win32, POSIX (Linux, BSD, etc.), Jython:

   http://pyserial.sourceforge.net

For Unix, see a Usenet post by Mitch Chapman:

   http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com


Why doesn't closing sys.stdout (stdin, stderr) really close it?
---------------------------------------------------------------

Python :term:`file objects <file object>` are a high-level layer of
abstraction on low-level C file descriptors.

For most file objects you create in Python via the built-in :func:`open`
function, ``f.close()`` marks the Python file object as being closed from
Python's point of view, and also arranges to close the underlying C file
descriptor.  This also happens automatically in ``f``'s destructor, when
``f`` becomes garbage.

But stdin, stdout and stderr are treated specially by Python, because of the
special status also given to them by C.  Running ``sys.stdout.close()`` marks
the Python-level file object as being closed, but does *not* close the
associated C file descriptor.

To close the underlying C file descriptor for one of these three, you should
first be sure that's what you really want to do (e.g., you may confuse
extension modules trying to do I/O).  If it is, use :func:`os.close`::

   os.close(stdin.fileno())
   os.close(stdout.fileno())
   os.close(stderr.fileno())

Or you can use the numeric constants 0, 1 and 2, respectively.


Network/Internet Programming
============================

What WWW tools are there for Python?
------------------------------------

See the chapters titled :ref:`internet` and :ref:`netdata` in the Library
Reference Manual.  Python has many modules that will help you build server-side
and client-side web systems.

.. XXX check if wiki page is still up to date

A summary of available frameworks is maintained by Paul Boddie at
http://wiki.python.org/moin/WebProgramming .

Cameron Laird maintains a useful set of pages about Python web technologies at
http://phaseit.net/claird/comp.lang.python/web_python.


How can I mimic CGI form submission (METHOD=POST)?
--------------------------------------------------

I would like to retrieve web pages that are the result of POSTing a form. Is
there existing code that would let me do this easily?

Yes. Here's a simple example that uses urllib.request::

   #!/usr/local/bin/python

   import urllib.request

   ### build the query string
   qs = "First=Josephine&MI=Q&Last=Public"

   ### connect and send the server a path
   req = urllib.request.urlopen('http://www.some-server.out-there'
                                '/cgi-bin/some-cgi-script', data=qs)
   msg, hdrs = req.read(), req.info()

Note that in general for percent-encoded POST operations, query strings must be
quoted using :func:`urllib.parse.urlencode`.  For example, to send
``name=Guy Steele, Jr.``::

   >>> import urllib.parse
   >>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
   'name=Guy+Steele%2C+Jr.'

.. seealso:: :ref:`urllib-howto` for extensive examples.


What module should I use to help with generating HTML?
------------------------------------------------------

.. XXX add modern template languages

You can find a collection of useful links on the `Web Programming wiki page
<http://wiki.python.org/moin/WebProgramming>`_.


How do I send mail from a Python script?
----------------------------------------

Use the standard library module :mod:`smtplib`.

Here's a very simple interactive mail sender that uses it.  This method will
work on any host that supports an SMTP listener. ::

   import sys, smtplib

   fromaddr = input("From: ")
   toaddrs  = input("To: ").split(',')
   print("Enter message, end with ^D:")
   msg = ''
   while True:
       line = sys.stdin.readline()
       if not line:
           break
       msg += line

   # The actual mail send
   server = smtplib.SMTP('localhost')
   server.sendmail(fromaddr, toaddrs, msg)
   server.quit()

A Unix-only alternative uses sendmail.  The location of the sendmail program
varies between systems; sometimes it is ``/usr/lib/sendmail``, sometimes
``/usr/sbin/sendmail``.  The sendmail manual page will help you out.  Here's
some sample code::

   SENDMAIL = "/usr/sbin/sendmail"  # sendmail location
   import os
   p = os.popen("%s -t -i" % SENDMAIL, "w")
   p.write("To: receiver@example.com\n")
   p.write("Subject: test\n")
   p.write("\n")  # blank line separating headers from body
   p.write("Some text\n")
   p.write("some more text\n")
   sts = p.close()
   if sts != 0:
       print("Sendmail exit status", sts)


How do I avoid blocking in the connect() method of a socket?
------------------------------------------------------------

The :mod:`select` module is commonly used to help with asynchronous I/O on
sockets.

To prevent the TCP connect from blocking, you can set the socket to non-blocking
mode.  Then when you do the ``connect()``, you will either connect immediately
(unlikely) or get an exception that contains the error number as ``.errno``.
``errno.EINPROGRESS`` indicates that the connection is in progress, but hasn't
finished yet.  Different OSes will return different values, so you're going to
have to check what's returned on your system.

You can use the ``connect_ex()`` method to avoid creating an exception.  It will
just return the errno value.  To poll, you can call ``connect_ex()`` again later
-- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this
socket to select to check if it's writable.

.. note::
   The :mod:`asyncore` module presents a framework-like approach to the problem
   of writing non-blocking networking code.
   The third-party `Twisted <http://twistedmatrix.com/>`_ library is
   a popular and feature-rich alternative.


Databases
=========

Are there any interfaces to database packages in Python?
--------------------------------------------------------

Yes.

Interfaces to disk-based hashes such as :mod:`DBM <dbm.ndbm>` and :mod:`GDBM
<dbm.gnu>` are also included with standard Python.  There is also the
:mod:`sqlite3` module, which provides a lightweight disk-based relational
database.

Support for most relational databases is available.  See the
`DatabaseProgramming wiki page
<http://wiki.python.org/moin/DatabaseProgramming>`_ for details.


How do you implement persistent objects in Python?
--------------------------------------------------

The :mod:`pickle` library module solves this in a very general way (though you
still can't store things like open files, sockets or windows), and the
:mod:`shelve` library module uses pickle and (g)dbm to create persistent
mappings containing arbitrary Python objects.


Mathematics and Numerics
========================

How do I generate random numbers in Python?
-------------------------------------------

The standard module :mod:`random` implements a random number generator.  Usage
is simple::

   import random
   random.random()

This returns a random floating point number in the range [0, 1).

There are also many other specialized generators in this module, such as:

* ``randrange(a, b)`` chooses an integer in the range [a, b).
* ``uniform(a, b)`` chooses a floating point number in the range [a, b).
* ``normalvariate(mean, sdev)`` samples the normal (Gaussian) distribution.

Some higher-level functions operate on sequences directly, such as:

* ``choice(S)`` chooses random element from a given sequence
* ``shuffle(L)`` shuffles a list in-place, i.e. permutes it randomly

There's also a ``Random`` class you can instantiate to create independent
multiple random number generators.
