Builtin Functions : Builtin Objects : sys-Module Functions : Examples : Structure : Download & Installation : Support : Copyright : History : Home | Version 1.0.0 |
As time passes there have often been situations where I thought "Hey, why not have this as builtin". In most cases the functions were easily coded in Python. But I started to use them quite heavily and since performance is always an issue (at least for me: hits/second pay my bills), I decided to code them in C. Well, that's how it started and here we are now with an ever growing number of goodies...
The functions defined by the C extensions are installed by the package at import time in different places of the Python interpreter. They work as fast add-ons to the existing set of functions and objects.
The following functions are installed as Python builtin
functions at package import time. They are then available as
normal builtin functions in every module without explicit
import in each module using them (though it is good practice
to still put a 'import NewBuiltins
' at the top
of each module relying on these add-ons).
indices(object)
tuple(range(len(object)))
-- a tad faster and a lot easier to type.
trange([start=0,]stop[,step=1])
range()
but returns a tuple instead of a list. Since
range()
is most often used in for-loops there
really is no need for a mutable data type and construction
of tuples is somewhat (20%) faster than that of lists. So
changing the usage of range()
in for-loops to
trange()
pays off in the long run.
range_len(object)
range(len(object))
.
tuples(sequence)
apply(map,(None,)+tuple(sequence))
does,
except that the resulting list will always have the length
of the first sub-sequence in sequence. The function
returns a list of tuples (a[0], b[0], c[0],...),
(a[1], b[1], c[1],...), ...
with missing elements
being filled in with None
.
Note that the function is of the single argument type
meaning that calling tuples(a,b,c)
is the
same as calling tuples((a,b,c))
. tuples()
can be used as inverse to lists().
lists(sequence)
reverse(sequence)
sequence
in reverse order. A tuple is
returned, if the sequence itself is a tuple. In all other
cases a list is returned.
dict(items)
setdict(sequence,value=None)
invdict(dictionary)
irange(object[,indices])
(index,object[index])
. If a sequence
indices
is given, the indices are read from
it. If not, then the index sequence defaults to
trange(len(object))
.
Note that object
can be any object that can
handle object[index]
, e.g. lists, tuples,
string, dictionaries, even your own objects, if they
provide a __getitem__-method. This makes very nifty
constructions possible and extracting items from another
sequence becomes a piece of cake. Give it a try ! You'll
soon love this little function.
ifilter(condition,object[,indices])
(index,object[index])
such that condition(object[index])
is true
and index is found in the sequence indices (defaulting to
trange(len(object))
). Order is
preserved. condition must be a callable object.
get(object,index[,default])
object[index]
, or, if that fails,
default
. If default
is not given
or the singleton NotGiven
an error is raised
(the error produced by the object).
extract(object,indices[,defaults])
object[index]
for
each index in the sequence indices
.
If a lookup fails and the sequence defaults
is given, then defaults[nth_index]
is used,
where nth_index
is the index of
index
in indices
(confused ?
it works as expected !). defaults
should
have the same length as indices
.
If you need the indices as well, try the
irange
function. The function raises an
IndexError
in case it can't find an entry
in indices or defaults.
iremove(object,indices)
This changes the object in place and thus is only possible for mutable types.
For sequences the index list must be sorted ascending;
an IndexError
will be raised otherwise (and
the object left in an undefined state).
findattr(object_list,attrname)
attrname
found among the objects in the
list. Raises an AttributeError
if the
attribute is not found.
attrlist(object_list,attrname)
attrname
found among the objects in the
list.
napply(number_of_calls,function[,args=(),kw={}])
number_of_calls
times with the same arguments and returns a tuple with the
return values. This is roughly equivalent to a for-loop
that repeatedly calls apply(function,args,kw)
and stores the return values in a tuple. Example: create
a tuple of 10 random integers... l =
napply(10,whrandom.randint,(0,10)).
mapply(callable_objects[,args=(),kw={}])
callable_objects
.
This function has a functionality dual to that of
map()
. While map()
applies
many different arguments to one callable object, this
function applies one set of arguments to many different
callable objects.
method_mapply(objects,methodname[,args=(),kw={}])
objects
.
A simple application is
e.g. method_mapply([a,b,c],'method', (x,y))
resulting in a tuple (a.method(x,y),
b.method(x,y), c.method(x,y))
. Thanks to Aaron
Waters for suggesting this function.
count(condition,sequence)
exists(condition,sequence)
forall(condition,sequence)
index(condition,sequence)
ValueError
is raised in case no item
is found. condition must be a callable object.
sizeof(object)
acquire(object,name)
This function can be used as __getattr__ hook in Python classes to enable implicit acquisition along a predefined lookup chain (object.baseobj provides a way to set up this chain). See Examples/Acquistion.py for some sample code.
defined(name)
The function has intimate knowledge about how symbol resolution works in Python: it first looks in locals(), then in globals() and if that fails in __builtins__.
A note on the naming scheme used:
i
stands for indexed, meaning that you have
access to indices
m
stands for multi, meaning that processing
involves multiple objects
n
stands for n-times, e.g. a function is
executed a certain number of times
t
stands for tuple
x
stands for lazy evaluation
Since this is (and will always be) work-in-progress, more functions will eventually turn up in this module, so stopping by every now and then is not a bad idea :-).
These objects are available after importing the package:
xmap(func, seq, [seq, seq, ...])
map(func,
seq, [seq, seq, ...])
.
The object behaves like a list, but evaluation of the function is postponed until a specific element from the list is requested. Unlike map, xmap can handle sequences not having a __len__ method defined (due to the evaluation-on-demand feature).
The xmap
objects define one method:
tolist()
This object is a contribution by Christopher Tavares (see xmap.c for his email address). I am providing this extension AS-IS, since I haven't had time to adapt it to my coding style.
NotGiven
None
. Its main
purpose is providing a way to indicate that a keyword was not
given in a call to a keyword capable function, e.g.
import NewBuiltins def f(a,b=4,c=NotGiven,d=''): if c is NotGiven: return a / b, d else: return a*b + c, d
It is also considered false in if
-statements, e.g.
import NewBuiltins a = NotGiven # ...init a conditionally... if not a: print 'a was not given as value'
True, False
(1==1) is
True
and (1==0) is False
.
The following functions are installed as add-ons to the builtin sys module.
sys.verbosity([level])
You can use this function to e.g. enable verborse lookup output to stderr for import statements even when the interpreter was not invoked with '-v' or '-vv' switch or to force verbosity to be switched off.
sys.optimization([level])
You can use this function to e.g. compile Python scripts in optimized mode even though the interpreter was not started with -O.
sys.cur_frame([offset=0])
Note: Storing the execution frame in a local variable introduces a circular reference, since the locals and globals are referenced in the execution frame, so use the return value with caution.
A few simple examples:
import NewBuiltins sequence = range(100) # In place calculations: for i,item in irange(sequence): sequence[i] = 2*item # Get all odd-indexed items from a sequence: odds = extract(sequence,trange(0,len(sequence),2)) # Turn a tuple of lists into a list of tuples: chars = 'abcdefghji' ords = map(ord,chars) table = tuples(chars,ords) # The same as dictionary: chr2ord = dict(table) # Inverse mapping: ord2chr = invdict(chr2ord) # Range checking: if exists( lambda x: x > 10, sequence ): print 'Warning: Big sequence elements!' # Handle special cases: if forall( lambda x: x > 0, sequence ): print 'Positive sequence' else: print 'Index %i loses' % (index( lambda x: x <= 0, sequence ),) # dict.get functionality for e.g. lists: print get(sequence,101,"Don't have an element with index 101")
More elaborate examples can be found in the Examples/
subdirectory of the package.
Entries enclosed in brackets are packages (i.e. they are
directories that include a __init__.py file) or
submodules. Ones with slashes are just ordinary
subdirectories that are not accessible via
Note: Importing
First, download the archive,
unzip it to a directory on your Python path
e.g. /usr/local/lib/python1.5/site-packages/ on
Unix or C:\Python\Lib\ under Windows and then
follow these steps:
Unix:
Instructions for compiling the C extension on Unix platforms:
Windows:
David Ascher has kindly provided pre-compiled Windows
versions of the extensions (version 0.9.0), so if you're
running WinXX, you can skip the following and start using
the package right away.
Instructions for compiling the C extension on Windows
platforms using VC++ (courtesy of Gordon McMillan):
MacOS:
Joseph Strout has sent me precompiled PowerMac binaries for
the C extensions (version 0.9.1). They are included in the
StuffIt file mxTools/maclibs.sit. To install them,
unstuff that file in the mxTools directory after
you have unzipped the archive in a directory on your Python
path. They should then be directly usable.
In case you run into problems or want to compile the modules
youself, see the Python Mac distribution docu or ask Joseph
Strout.
Though the module has been tested, there may still be some
bugs left. Please post any bug reports, questions
etc. directly to me.
I am providing commercial support for this package through
Python Professional
Services Inc.. Please see their website for details.
© 1997, 1998, Copyright by Marc-André Lemburg; All
Rights Reserved. mailto: mal@lemburg.com
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without fee
or royalty is hereby granted, provided that the above
copyright notice appear in all copies and that both the
copyright notice and this permission notice appear in
supporting documentation or portions thereof, including
modifications, that you make.
THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE !
Changes from 0.9.1 to 1.0.0:
Changes from 0.9.0 to 0.9.1:
Changes from 0.8.1 to 0.9.0:
Changes from 0.7 to 0.8:
Changes from 0.6 to 0.7:
Changes from 0.5 to 0.6:
Changes from 0.4 to 0.5:
Changes from 0.3 to 0.4:
Package Structure
[NewBuiltins]
Doc/
[Examples]
Acquisition.py
[mxTools]
test.py
NewBuiltins.py
import
.
NewBuiltins
will
automatically install the functions and objects defined in
this package as builtins. They are then available in all
other modules without having to import then again every
time. If you don't want this feature, you can turn it off in
NewBuiltins/__init__.py.
Installation
Support
What I'd like to hear from you...
Copyright & Disclaimer
History & Future