[Python-Dev] inheriting basic types more efficiently

Dennis Heuer dh at triple-media.com
Wed Apr 26 23:08:20 CEST 2006

OK, let's get back to the bitarray type. To first be clear about the
*type* of bitarray: The type I talk about is really a *bit*-array and
not a *bytewise*-array, as most developers seem to think of it. The
array doesn't provide the boolean manipulation of single bytes in the
array, it provides the manipulation of single bits or slices of bits in
a bit sequence of unlimited length. Think of it like of a data sequence
for a touring mashine (just bits).

The reason why I'd like to use the long type as the base of my bitarray
type is that the long type is already implemented as an array and
working efficiently with large amounts of bytes. Also, it already
supports a lot of necessary (including boolean) operators. The slicing/
manipulation of ranges can be implemented in the bitarray class. That's
working similar to the example below:

class bitarray(long):
    def __setitem__(self, key, value):

        # in this example only decimal values are supported
        if type(value) not in (int, long):
            raise ValueError
        # slices are supported
        if type(key) not in (int, long, slice):
            raise KeyError
        # checking if the target is a single bit
        if type(key) in (int, long) and value not in (0, 1):
            raise ValueError
        # checking if a range of bits is targeted and if the value fits
        if type(key) == slice:
            # let's assume that the slice object 
            # provides only positive values and
            # that step is set to default (1)
            if value < 0 or value > (key.stop - key.start):
                raise ValueError
            key = key.start # only the offset is needed from now on
        # pushing up value to the offset
        # and adding it to the bit sequence
        long.__add__(2**key * value) # Should actually overwrite the
                                     # range but I couldn't even get
                                     # this to work. long complains
                                     # about the value being of type
                                     # int. But how can I convert it
                                     # to long if the term long is
                                     # already reserved for the
                                     # superclass? At least I was
                                     # too stupid to find it out.

This small hack shows well that the long type could be a very good base
for the bitarray type when it comes to processing (what comes out).
However, when it comes to retrieving (what comes in), the situation is
quite different. The bitarray type is a type for fiddling around. It
shall also provide configurable truthtables and carry rules. To be able
to work with the bitarray type more *natively*, it shall support
bitstring input like "101010". But if the bitarray type is based on the
long type and one tries the following:

x = bitarray()
x += "101010"

the above bitstring is interpreted as the decimal value 101010, which
is wrong. There seems to be no other way to change this than
overwriting all the inherited methods to let them interpret the
bitstring correctly. This is counterproductive.

If there was a way to advice the interpreter to *filter* the input
values before they are passed to the called attribute, one could keep
the original methods of the long type and still provide bitstring input
support. A method like __validate__ or similar could provide this
filter. The interpreter first calls __validate__ to receive the return
values and pass them on to the called method/attribute.

Do you now understand the case?


On Wed, 26 Apr 2006 10:47:55 -0700
"Guido van Rossum" <guido at python.org> wrote:

> I doubt you'll get many answers. I have no idea what you're talking
> about. How about an example or two?
> On 4/26/06, Dennis Heuer <dh at triple-media.com> wrote:
> > To bring the real problem more upfront. Up to now, inheriting classes
> > is all about processing (the output channel) but not about retrieving
> > (the input channel). However, though a new type can advance from an
> > existing type if it just needs to provide some few more methods, it can
> > not advance from an existing type if it needs to support some few other
> > input formats--even if they all convert to the inherited type easily.
> > The input channel is completely forgotten.
> --
> --Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list