\section{Built-in Functions \label{built-in-funcs}}

The Python interpreter has a number of functions built into it that
are always available.  They are listed here in alphabetical order.


\setindexsubitem{(built-in function)}

\begin{funcdesc}{__import__}{name\optional{, globals\optional{, locals\optional{, fromlist}}}}
This function is invoked by the
\keyword{import}\stindex{import} statement.  It mainly
exists so that you can replace it with another function that has a
compatible interface, in order to change the semantics of the
\keyword{import} statement.  For examples of why and how you would do
this, see the standard library modules
\module{ihooks}\refstmodindex{ihooks} and
\refmodule{rexec}\refstmodindex{rexec}.  See also the built-in module
\refmodule{imp}\refbimodindex{imp}, which defines some useful
operations out of which you can build your own
\function{__import__()} function.

For example, the statement \samp{import spam} results in the
following call:
\code{__import__('spam',} \code{globals(),} \code{locals(), [])};
the statement \samp{from spam.ham import eggs} results
in \samp{__import__('spam.ham', globals(), locals(), ['eggs'])}.
Note that even though \code{locals()} and \code{['eggs']} are passed
in as arguments, the \function{__import__()} function does not set the
local variable named \code{eggs}; this is done by subsequent code that
is generated for the import statement.  (In fact, the standard
implementation does not use its \var{locals} argument at all, and uses
its \var{globals} only to determine the package context of the
\keyword{import} statement.)

When the \var{name} variable is of the form \code{package.module},
normally, the top-level package (the name up till the first dot) is
returned, \emph{not} the module named by \var{name}.  However, when a
non-empty \var{fromlist} argument is given, the module named by
\var{name} is returned.  This is done for compatibility with the
bytecode generated for the different kinds of import statement; when
using \samp{import spam.ham.eggs}, the top-level package \code{spam}
must be placed in the importing namespace, but when using \samp{from
spam.ham import eggs}, the \code{spam.ham} subpackage must be used to
find the \code{eggs} variable.
As a workaround for this behavior, use \function{getattr()} to extract
the desired components.  For example, you could define the following
helper:

\begin{verbatim}
import string

def my_import(name):
    mod = __import__(name)
    components = string.split(name, '.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod
\end{verbatim}

\end{funcdesc}

\begin{funcdesc}{abs}{x}
  Return the absolute value of a number.  The argument may be a plain
  or long integer or a floating point number.  If the argument is a
  complex number, its magnitude is returned.
\end{funcdesc}

\begin{funcdesc}{apply}{function, args\optional{, keywords}}
The \var{function} argument must be a callable object (a user-defined or
built-in function or method, or a class object) and the \var{args}
argument must be a sequence (if it is not a tuple, the sequence is
first converted to a tuple).  The \var{function} is called with
\var{args} as the argument list; the number of arguments is the the length
of the tuple.  (This is different from just calling
\code{\var{func}(\var{args})}, since in that case there is always
exactly one argument.)
If the optional \var{keywords} argument is present, it must be a
dictionary whose keys are strings.  It specifies keyword arguments to
be added to the end of the the argument list.
\end{funcdesc}

\begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}}
The \var{object} argument must be an object that supports the
buffer call interface (such as strings, arrays, and buffers). A new
buffer object will be created which references the \var{object} argument.
The buffer object will be a slice from the beginning of \var{object}
(or from the specified \var{offset}). The slice will extend to the
end of \var{object} (or will have a length given by the \var{size}
argument).
\end{funcdesc}

\begin{funcdesc}{callable}{object}
Return true if the \var{object} argument appears callable, false if
not.  If this returns true, it is still possible that a call fails,
but if it is false, calling \var{object} will never succeed.  Note
that classes are callable (calling a class returns a new instance);
class instances are callable if they have a \method{__call__()} method.
\end{funcdesc}

\begin{funcdesc}{chr}{i}
  Return a string of one character whose \ASCII{} code is the integer
  \var{i}, e.g., \code{chr(97)} returns the string \code{'a'}.  This is the
  inverse of \function{ord()}.  The argument must be in the range [0..255],
  inclusive; \exception{ValueError} will be raised if \var{i} is
  outside that range.
\end{funcdesc}

\begin{funcdesc}{cmp}{x, y}
  Compare the two objects \var{x} and \var{y} and return an integer
  according to the outcome.  The return value is negative if \code{\var{x}
  < \var{y}}, zero if \code{\var{x} == \var{y}} and strictly positive if
  \code{\var{x} > \var{y}}.
\end{funcdesc}

\begin{funcdesc}{coerce}{x, y}
  Return a tuple consisting of the two numeric arguments converted to
  a common type, using the same rules as used by arithmetic
  operations.
\end{funcdesc}

\begin{funcdesc}{compile}{string, filename, kind}
  Compile the \var{string} into a code object.  Code objects can be
  executed by an \keyword{exec} statement or evaluated by a call to
  \function{eval()}.  The \var{filename} argument should
  give the file from which the code was read; pass e.g. \code{'<string>'}
  if it wasn't read from a file.  The \var{kind} argument specifies
  what kind of code must be compiled; it can be \code{'exec'} if
  \var{string} consists of a sequence of statements, \code{'eval'}
  if it consists of a single expression, or \code{'single'} if
  it consists of a single interactive statement (in the latter case,
  expression statements that evaluate to something else than
  \code{None} will printed).
\end{funcdesc}

\begin{funcdesc}{complex}{real\optional{, imag}}
  Create a complex number with the value \var{real} + \var{imag}*j or
  convert a string or number to a complex number.
  Each argument may be any numeric type (including complex).
  If \var{imag} is omitted, it defaults to zero and the function
  serves as a numeric conversion function like \function{int()},
  \function{long()} and \function{float()}; in this case it also
  accepts a string argument which should be a valid complex number.
\end{funcdesc}

\begin{funcdesc}{delattr}{object, name}
  This is a relative of \function{setattr()}.  The arguments are an
  object and a string.  The string must be the name
  of one of the object's attributes.  The function deletes
  the named attribute, provided the object allows it.  For example,
  \code{delattr(\var{x}, '\var{foobar}')} is equivalent to
  \code{del \var{x}.\var{foobar}}.
\end{funcdesc}

\begin{funcdesc}{dir}{\optional{object}}
  Without arguments, return the list of names in the current local
  symbol table.  With an argument, attempts to return a list of valid
  attribute for that object.  This information is gleaned from the
  object's \member{__dict__}, \member{__methods__} and \member{__members__}
  attributes, if defined.  The list is not necessarily complete; e.g.,
  for classes, attributes defined in base classes are not included,
  and for class instances, methods are not included.
  The resulting list is sorted alphabetically.  For example:

\begin{verbatim}
>>> import sys
>>> dir()
['sys']
>>> dir(sys)
['argv', 'exit', 'modules', 'path', 'stderr', 'stdin', 'stdout']
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{divmod}{a, b}
  Take two numbers as arguments and return a pair of numbers consisting
  of their quotient and remainder when using long division.  With mixed
  operand types, the rules for binary arithmetic operators apply.  For
  plain and long integers, the result is the same as
  \code{(\var{a} / \var{b}, \var{a} \%{} \var{b})}.
  For floating point numbers the result is \code{(\var{q}, \var{a} \%{}
  \var{b})}, where \var{q} is usually \code{math.floor(\var{a} /
  \var{b})} but may be 1 less than that.  In any case \code{\var{q} *
  \var{b} + \var{a} \%{} \var{b}} is very close to \var{a}, if
  \code{\var{a} \%{} \var{b}} is non-zero it has the same sign as
  \var{b}, and \code{0 <= abs(\var{a} \%{} \var{b}) < abs(\var{b})}.
\end{funcdesc}

\begin{funcdesc}{eval}{expression\optional{, globals\optional{, locals}}}
  The arguments are a string and two optional dictionaries.  The
  \var{expression} argument is parsed and evaluated as a Python
  expression (technically speaking, a condition list) using the
  \var{globals} and \var{locals} dictionaries as global and local name
  space.  If the \var{locals} dictionary is omitted it defaults to
  the \var{globals} dictionary.  If both dictionaries are omitted, the
  expression is executed in the environment where \keyword{eval} is
  called.  The return value is the result of the evaluated expression.
  Syntax errors are reported as exceptions.  Example:

\begin{verbatim}
>>> x = 1
>>> print eval('x+1')
2
\end{verbatim}

  This function can also be used to execute arbitrary code objects
  (e.g.\ created by \function{compile()}).  In this case pass a code
  object instead of a string.  The code object must have been compiled
  passing \code{'eval'} to the \var{kind} argument.

  Hints: dynamic execution of statements is supported by the
  \keyword{exec} statement.  Execution of statements from a file is
  supported by the \function{execfile()} function.  The
  \function{globals()} and \function{locals()} functions returns the
  current global and local dictionary, respectively, which may be
  useful to pass around for use by \function{eval()} or
  \function{execfile()}.
\end{funcdesc}

\begin{funcdesc}{execfile}{file\optional{, globals\optional{, locals}}}
  This function is similar to the
  \keyword{exec} statement, but parses a file instead of a string.  It
  is different from the \keyword{import} statement in that it does not
  use the module administration --- it reads the file unconditionally
  and does not create a new module.\footnote{It is used relatively
  rarely so does not warrant being made into a statement.}

  The arguments are a file name and two optional dictionaries.  The
  file is parsed and evaluated as a sequence of Python statements
  (similarly to a module) using the \var{globals} and \var{locals}
  dictionaries as global and local namespace.  If the \var{locals}
  dictionary is omitted it defaults to the \var{globals} dictionary.
  If both dictionaries are omitted, the expression is executed in the
  environment where \function{execfile()} is called.  The return value is
  \code{None}.
\end{funcdesc}

\begin{funcdesc}{filter}{function, list}
Construct a list from those elements of \var{list} for which
\var{function} returns true.  If \var{list} is a string or a tuple,
the result also has that type; otherwise it is always a list.  If
\var{function} is \code{None}, the identity function is assumed,
i.e.\ all elements of \var{list} that are false (zero or empty) are
removed.
\end{funcdesc}

\begin{funcdesc}{float}{x}
  Convert a string or a number to floating point.  If the argument is a
  string, it must contain a possibly signed decimal or floating point
  number, possibly embedded in whitespace; this behaves identical to
  \code{string.atof(\var{x})}.  Otherwise, the argument may be a plain
  or long integer or a floating point number, and a floating point
  number with the same value (within Python's floating point
  precision) is returned.

  \strong{Note:} When passing in a string, values for NaN\index{NaN}
  and Infinity\index{Infinity} may be returned, depending on the
  underlying C library.  The specific set of strings accepted which
  cause these values to be returned depends entirely on the C library
  and is known to vary.
\end{funcdesc}

\begin{funcdesc}{getattr}{object, name\optional{, default}}
  Return the value of the named attributed of \var{object}.  \var{name}
  must be a string.  If the string is the name of one of the object's
  attributes, the result is the value of that attribute.  For example,
  \code{getattr(x, 'foobar')} is equivalent to \code{x.foobar}.  If the
  named attribute does not exist, \var{default} is returned if provided,
  otherwise \exception{AttributeError} is raised.
\end{funcdesc}

\begin{funcdesc}{globals}{}
Return a dictionary representing the current global symbol table.
This is always the dictionary of the current module (inside a
function or method, this is the module where it is defined, not the
module from which it is called).
\end{funcdesc}

\begin{funcdesc}{hasattr}{object, name}
  The arguments are an object and a string.  The result is 1 if the
  string is the name of one of the object's attributes, 0 if not.
  (This is implemented by calling \code{getattr(\var{object},
  \var{name})} and seeing whether it raises an exception or not.)
\end{funcdesc}

\begin{funcdesc}{hash}{object}
  Return the hash value of the object (if it has one).  Hash values
  are integers.  They are used to quickly compare dictionary
  keys during a dictionary lookup.  Numeric values that compare equal
  have the same hash value (even if they are of different types, e.g.
  1 and 1.0).
\end{funcdesc}

\begin{funcdesc}{hex}{x}
  Convert an integer number (of any size) to a hexadecimal string.
  The result is a valid Python expression.  Note: this always yields
  an unsigned literal, e.g. on a 32-bit machine, \code{hex(-1)} yields
  \code{'0xffffffff'}.  When evaluated on a machine with the same
  word size, this literal is evaluated as -1; at a different word
  size, it may turn up as a large positive number or raise an
  \exception{OverflowError} exception.
\end{funcdesc}

\begin{funcdesc}{id}{object}
  Return the `identity' of an object.  This is an integer (or long
  integer) which is guaranteed to be unique and constant for this
  object during its lifetime.  Two objects whose lifetimes are
  disjunct may have the same \function{id()} value.  (Implementation
  note: this is the address of the object.)
\end{funcdesc}

\begin{funcdesc}{input}{\optional{prompt}}
  Equivalent to \code{eval(raw_input(\var{prompt}))}.
  \strong{Warning:} This function is not safe from user errors!  It
  expects a valid Python expression as input; if the input is not
  syntactically valid, a \exception{SyntaxError} will be raised.
  Other exceptions may be raised if there is an error during
  evaluation.  (On the other hand, sometimes this is exactly what you
  need when writing a quick script for expert use.)

  If the \module{readline} module was loaded, then
  \function{input()} will use it to provide elaborate line editing and
  history features.

  Consider using the \function{raw_input()} function for general input
  from users.
\end{funcdesc}

\begin{funcdesc}{int}{x\optional{, radix}}
  Convert a string or number to a plain integer.  If the argument is a
  string, it must contain a possibly signed decimal number
  representable as a Python integer, possibly embedded in whitespace;
  this behaves identical to \code{string.atoi(\var{x}\optional{,
  \var{radix}})}.  The \var{radix} parameter gives the base for the
  conversion and may be any integer in the range [2, 36], or zero.  If
  \var{radix} is zero, the proper radix is guessed based on the
  contents of string; the interpretation is the same as for integer
  literals.  If \var{radix} is specified and \var{x} is not a string,
  \exception{TypeError} is raised.
  Otherwise, the argument may be a plain or
  long integer or a floating point number.  Conversion of floating
  point numbers to integers is defined by the C semantics; normally
  the conversion truncates towards zero.\footnote{This is ugly --- the
  language definition should require truncation towards zero.}
\end{funcdesc}

\begin{funcdesc}{intern}{string}
  Enter \var{string} in the table of ``interned'' strings and return
  the interned string -- which is \var{string} itself or a copy.
  Interning strings is useful to gain a little performance on
  dictionary lookup -- if the keys in a dictionary are interned, and
  the lookup key is interned, the key comparisons (after hashing) can
  be done by a pointer compare instead of a string compare.  Normally,
  the names used in Python programs are automatically interned, and
  the dictionaries used to hold module, class or instance attributes
  have interned keys.  Interned strings are immortal (i.e. never get
  garbage collected).
\end{funcdesc}

\begin{funcdesc}{isinstance}{object, class}
Return true if the \var{object} argument is an instance of the
\var{class} argument, or of a (direct or indirect) subclass thereof.
Also return true if \var{class} is a type object and \var{object} is
an object of that type.  If \var{object} is not a class instance or a
object of the given type, the function always returns false.  If
\var{class} is neither a class object nor a type object, a
\exception{TypeError} exception is raised.
\end{funcdesc}

\begin{funcdesc}{issubclass}{class1, class2}
Return true if \var{class1} is a subclass (direct or indirect) of
\var{class2}.  A class is considered a subclass of itself.  If either
argument is not a class object, a \exception{TypeError} exception is
raised.
\end{funcdesc}

\begin{funcdesc}{len}{s}
  Return the length (the number of items) of an object.  The argument
  may be a sequence (string, tuple or list) or a mapping (dictionary).
\end{funcdesc}

\begin{funcdesc}{list}{sequence}
Return a list whose items are the same and in the same order as
\var{sequence}'s items.  If \var{sequence} is already a list,
a copy is made and returned, similar to \code{\var{sequence}[:]}.  
For instance, \code{list('abc')} returns
returns \code{['a', 'b', 'c']} and \code{list( (1, 2, 3) )} returns
\code{[1, 2, 3]}.
\end{funcdesc}

\begin{funcdesc}{locals}{}
Return a dictionary representing the current local symbol table.
\strong{Warning:} The contents of this dictionary should not be
modified; changes may not affect the values of local variables used by 
the interpreter.
\end{funcdesc}

\begin{funcdesc}{long}{x\optional{, radix}}
  Convert a string or number to a long integer.  If the argument is a
  string, it must contain a possibly signed number of
  arbitrary size, possibly embedded in whitespace;
  this behaves identical to \code{string.atol(\var{x})}.  The
  \var{radix} argument is interpreted in the same way as for
  \function{int()}, and may only be given when \var{x} is a string.
  Otherwise, the argument may be a plain or
  long integer or a floating point number, and a long integer with
  the same value is returned.    Conversion of floating
  point numbers to integers is defined by the C semantics;
  see the description of \function{int()}.
\end{funcdesc}

\begin{funcdesc}{map}{function, list, ...}
Apply \var{function} to every item of \var{list} and return a list
of the results.  If additional \var{list} arguments are passed, 
\var{function} must take that many arguments and is applied to
the items of all lists in parallel; if a list is shorter than another
it is assumed to be extended with \code{None} items.  If
\var{function} is \code{None}, the identity function is assumed; if
there are multiple list arguments, \function{map()} returns a list
consisting of tuples containing the corresponding items from all lists
(i.e. a kind of transpose operation).  The \var{list} arguments may be
any kind of sequence; the result is always a list.
\end{funcdesc}

\begin{funcdesc}{max}{s\optional{, args...}}
With a single argument \var{s}, return the largest item of a
non-empty sequence (e.g., a string, tuple or list).  With more than
one argument, return the largest of the arguments.
\end{funcdesc}

\begin{funcdesc}{min}{s\optional{, args...}}
With a single argument \var{s}, return the smallest item of a
non-empty sequence (e.g., a string, tuple or list).  With more than
one argument, return the smallest of the arguments.
\end{funcdesc}

\begin{funcdesc}{oct}{x}
  Convert an integer number (of any size) to an octal string.  The
  result is a valid Python expression.  Note: this always yields
  an unsigned literal, e.g. on a 32-bit machine, \code{oct(-1)} yields
  \code{'037777777777'}.  When evaluated on a machine with the same
  word size, this literal is evaluated as -1; at a different word
  size, it may turn up as a large positive number or raise an
  \exception{OverflowError} exception.
\end{funcdesc}

\begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}}
  Return a new file object (described earlier under Built-in Types).
  The first two arguments are the same as for \code{stdio}'s
  \cfunction{fopen()}: \var{filename} is the file name to be opened,
  \var{mode} indicates how the file is to be opened: \code{'r'} for
  reading, \code{'w'} for writing (truncating an existing file), and
  \code{'a'} opens it for appending (which on \emph{some} \UNIX{}
  systems means that \emph{all} writes append to the end of the file,
  regardless of the current seek position).

  Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for
  updating (note that \code{'w+'} truncates the file).  Append
  \code{'b'} to the mode to open the file in binary mode, on systems
  that differentiate between binary and text files (else it is
  ignored).  If the file cannot be opened, \exception{IOError} is
  raised.

  If \var{mode} is omitted, it defaults to \code{'r'}.  When opening a 
  binary file, you should append \code{'b'} to the \var{mode} value
  for improved portability.  (It's useful even on systems which don't
  treat binary and text files differently, where it serves as
  documentation.)
  \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O}
  \index{I/O control!buffering}
  The optional \var{bufsize} argument specifies the
  file's desired buffer size: 0 means unbuffered, 1 means line
  buffered, any other positive value means use a buffer of
  (approximately) that size.  A negative \var{bufsize} means to use
  the system default, which is usually line buffered for for tty
  devices and fully buffered for other files.  If omitted, the system
  default is used.\footnote{
    Specifying a buffer size currently has no effect on systems that
    don't have \cfunction{setvbuf()}.  The interface to specify the
    buffer size is not done using a method that calls
    \cfunction{setvbuf()}, because that may dump core when called
    after any I/O has been performed, and there's no reliable way to
    determine whether this is the case.}
\end{funcdesc}

\begin{funcdesc}{ord}{c}
  Return the \ASCII{} value of a string of one character or a Unicode
  character.  E.g., \code{ord('a')} returns the integer \code{97},
  \code{ord(u'\\u2020')} returns \code{8224}.  This is the inverse of
  \function{chr()} for strings and of \function{unichr()} for Unicode
  characters.
\end{funcdesc}

\begin{funcdesc}{pow}{x, y\optional{, z}}
  Return \var{x} to the power \var{y}; if \var{z} is present, return
  \var{x} to the power \var{y}, modulo \var{z} (computed more
  efficiently than \code{pow(\var{x}, \var{y}) \%\ \var{z}}).
  The arguments must have
  numeric types.  With mixed operand types, the rules for binary
  arithmetic operators apply.  The effective operand type is also the
  type of the result; if the result is not expressible in this type, the
  function raises an exception; e.g., \code{pow(2, -1)} or \code{pow(2,
  35000)} is not allowed.
\end{funcdesc}

\begin{funcdesc}{range}{\optional{start,} stop\optional{, step}}
  This is a versatile function to create lists containing arithmetic
  progressions.  It is most often used in \keyword{for} loops.  The
  arguments must be plain integers.  If the \var{step} argument is
  omitted, it defaults to \code{1}.  If the \var{start} argument is
  omitted, it defaults to \code{0}.  The full form returns a list of
  plain integers \code{[\var{start}, \var{start} + \var{step},
  \var{start} + 2 * \var{step}, \ldots]}.  If \var{step} is positive,
  the last element is the largest \code{\var{start} + \var{i} *
  \var{step}} less than \var{stop}; if \var{step} is negative, the last
  element is the largest \code{\var{start} + \var{i} * \var{step}}
  greater than \var{stop}.  \var{step} must not be zero (or else
  \exception{ValueError} is raised).  Example:

\begin{verbatim}
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{raw_input}{\optional{prompt}}
  If the \var{prompt} argument is present, it is written to standard output
  without a trailing newline.  The function then reads a line from input,
  converts it to a string (stripping a trailing newline), and returns that.
  When \EOF{} is read, \exception{EOFError} is raised. Example:

\begin{verbatim}
>>> s = raw_input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"
\end{verbatim}

If the \module{readline} module was loaded, then
\function{raw_input()} will use it to provide elaborate
line editing and history features.
\end{funcdesc}

\begin{funcdesc}{reduce}{function, sequence\optional{, initializer}}
Apply \var{function} of two arguments cumulatively to the items of
\var{sequence}, from left to right, so as to reduce the sequence to
a single value.  For example,
\code{reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])} calculates
\code{((((1+2)+3)+4)+5)}.
If the optional \var{initializer} is present, it is placed before the
items of the sequence in the calculation, and serves as a default when
the sequence is empty.
\end{funcdesc}

\begin{funcdesc}{reload}{module}
Re-parse and re-initialize an already imported \var{module}.  The
argument must be a module object, so it must have been successfully
imported before.  This is useful if you have edited the module source
file using an external editor and want to try out the new version
without leaving the Python interpreter.  The return value is the
module object (i.e.\ the same as the \var{module} argument).

There are a number of caveats:

If a module is syntactically correct but its initialization fails, the
first \keyword{import} statement for it does not bind its name locally,
but does store a (partially initialized) module object in
\code{sys.modules}.  To reload the module you must first
\keyword{import} it again (this will bind the name to the partially
initialized module object) before you can \function{reload()} it.

When a module is reloaded, its dictionary (containing the module's
global variables) is retained.  Redefinitions of names will override
the old definitions, so this is generally not a problem.  If the new
version of a module does not define a name that was defined by the old
version, the old definition remains.  This feature can be used to the
module's advantage if it maintains a global table or cache of objects
--- with a \keyword{try} statement it can test for the table's presence
and skip its initialization if desired.

It is legal though generally not very useful to reload built-in or
dynamically loaded modules, except for \module{sys}, \module{__main__}
and \module{__builtin__}.  In many cases, however, extension
modules are not designed to be initialized more than once, and may
fail in arbitrary ways when reloaded.

If a module imports objects from another module using \keyword{from}
\ldots{} \keyword{import} \ldots{}, calling \function{reload()} for
the other module does not redefine the objects imported from it ---
one way around this is to re-execute the \keyword{from} statement,
another is to use \keyword{import} and qualified names
(\var{module}.\var{name}) instead.

If a module instantiates instances of a class, reloading the module
that defines the class does not affect the method definitions of the
instances --- they continue to use the old class definition.  The same
is true for derived classes.
\end{funcdesc}

\begin{funcdesc}{repr}{object}
Return a string containing a printable representation of an object.
This is the same value yielded by conversions (reverse quotes).
It is sometimes useful to be able to access this operation as an
ordinary function.  For many types, this function makes an attempt
to return a string that would yield an object with the same value
when passed to \function{eval()}.
\end{funcdesc}

\begin{funcdesc}{round}{x\optional{, n}}
  Return the floating point value \var{x} rounded to \var{n} digits
  after the decimal point.  If \var{n} is omitted, it defaults to zero.
  The result is a floating point number.  Values are rounded to the
  closest multiple of 10 to the power minus \var{n}; if two multiples
  are equally close, rounding is done away from 0 (so e.g.
  \code{round(0.5)} is \code{1.0} and \code{round(-0.5)} is \code{-1.0}).
\end{funcdesc}

\begin{funcdesc}{setattr}{object, name, value}
  This is the counterpart of \function{getattr()}.  The arguments are an
  object, a string and an arbitrary value.  The string may name an
  existing attribute or a new attribute.  The function assigns the
  value to the attribute, provided the object allows it.  For example,
  \code{setattr(\var{x}, '\var{foobar}', 123)} is equivalent to
  \code{\var{x}.\var{foobar} = 123}.
\end{funcdesc}

\begin{funcdesc}{slice}{\optional{start,} stop\optional{, step}}
Return a slice object representing the set of indices specified by
\code{range(\var{start}, \var{stop}, \var{step})}.  The \var{start}
and \var{step} arguments default to None.  Slice objects have
read-only data attributes \member{start}, \member{stop} and \member{step}
which merely return the argument values (or their default).  They have
no other explicit functionality; however they are used by Numerical
Python\index{Numerical Python} and other third party extensions.
Slice objects are also generated when extended indexing syntax is
used, e.g. for \samp{a[start:stop:step]} or \samp{a[start:stop, i]}.
\end{funcdesc}

\begin{funcdesc}{str}{object}
Return a string containing a nicely printable representation of an
object.  For strings, this returns the string itself.  The difference
with \code{repr(\var{object})} is that \code{str(\var{object})} does not
always attempt to return a string that is acceptable to \function{eval()};
its goal is to return a printable string.
\end{funcdesc}

\begin{funcdesc}{tuple}{sequence}
Return a tuple whose items are the same and in the same order as
\var{sequence}'s items.  If \var{sequence} is already a tuple, it
is returned unchanged.  For instance, \code{tuple('abc')} returns
returns \code{('a', 'b', 'c')} and \code{tuple([1, 2, 3])} returns
\code{(1, 2, 3)}.
\end{funcdesc}

\begin{funcdesc}{type}{object}
Return the type of an \var{object}.  The return value is a type
object.  The standard module \module{types} defines names for all
built-in types.
\refstmodindex{types}
\obindex{type}
For instance:

\begin{verbatim}
>>> import types
>>> if type(x) == types.StringType: print "It's a string"
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{unichr}{i}
Return the Unicode string of one character whose Unicode code is the
integer \var{i}, e.g., \code{unichr(97)} returns the string
\code{u'a'}.  This is the inverse of \function{ord()} for Unicode
strings.  The argument must be in the range [0..65535], inclusive.
\exception{ValueError} is raised otherwise.
\versionadded{2.0}
\end{funcdesc}

\begin{funcdesc}{unicode}{string\optional{, encoding\optional{, errors}}}
Decodes \var{string} using the codec for \var{encoding}.  Error
handling is done according to \var{errors}.  The default behavior is
to decode UTF-8 in strict mode, meaning that encoding errors raise
\exception{ValueError}.  See also the \refmodule{codecs} module.
\versionadded{2.0}
\end{funcdesc}

\begin{funcdesc}{vars}{\optional{object}}
Without arguments, return a dictionary corresponding to the current
local symbol table.  With a module, class or class instance object as
argument (or anything else that has a \member{__dict__} attribute),
returns a dictionary corresponding to the object's symbol table.
The returned dictionary should not be modified: the effects on the
corresponding symbol table are undefined.\footnote{
  In the current implementation, local variable bindings cannot
  normally be affected this way, but variables retrieved from 
  other scopes (e.g. modules) can be.  This may change.}
\end{funcdesc}

\begin{funcdesc}{xrange}{\optional{start,} stop\optional{, step}}
This function is very similar to \function{range()}, but returns an
``xrange object'' instead of a list.  This is an opaque sequence type
which yields the same values as the corresponding list, without
actually storing them all simultaneously.  The advantage of
\function{xrange()} over \function{range()} is minimal (since
\function{xrange()} still has to create the values when asked for
them) except when a very large range is used on a memory-starved
machine (e.g. MS-DOS) or when all of the range's elements are never
used (e.g. when the loop is usually terminated with \keyword{break}).
\end{funcdesc}

\begin{funcdesc}{zip}{seq1, \moreargs}
This function returns a list of tuples, where each tuple contains the
\var{i}-th element from each of the argument sequences.  At least one
sequence is required, otherwise a \exception{TypeError} is raised.
The returned list is truncated in length to the length of the shortest
argument sequence.  When there are multiple argument sequences which
are all of the same length, \function{zip()} is similar to
\function{map()} with an initial argument of \code{None}.  With a
single sequence argument, it returns a list of 1-tuples.
\versionadded{2.0}
\end{funcdesc}
