changing value of 'self' when subclassing int

Nick Craig-Wood nick at craig-wood.com
Tue Feb 21 07:30:04 EST 2006


David Coffin <dcoffin at gmail.com> wrote:
>  I'd like to subclass int to support list access, treating the integer  
>  as if it were a list of bits.
>  Assigning bits to particular indices involves changing the value of  
>  the integer itself, but changing 'self' obviously just alters the  
>  value of that local variable.
>  Is there some way for me to change the value of the BitSequence  
>  object itself? I've also tried wrapping and delegating using  
>  __getattr__, but I couldn't figure out how to handle in-place
>  methods.

Here was my take on the problem when it came up for me.  Note the
FIXMEs ;-) My first attempt was to subclass long which was a dismal
failure.

class bits:
    """
    Space efficient bit storage.  It returns something which acts
    like an infinitely long array.  The array is initialised to all 0s

    FIXME need to implement lots more methods!
    FIXME check for -ve indices etc!
    FIXME can do boolean methods by arithmetic on longs
    FIXME can't subclass long as long is immutable :-(
    """
    def __init__(self, initial = None):
        "Initialise with the initial state of the array or nothing for it to be set to all 0s"
        self.i = 0L
        if initial:
            for i in initial:
                self.i <<= 1
                self.i |= i
    def mask(self, n):
        return 1L << n
    def __getitem__(self, n):
        return (self.i & self.mask(n)) != 0L
    def __setitem__(self, n, v):
        m = self.mask(n)
        if v:
            self.i |= m
        elif self.i & m:
            self.i ^= m
    # FIXME implement len() and use it in __repr__ to output directly!
    def __repr__(self):
        # FIXME is there a way to convert a long to binary?
        content = ""
        if self.i:
            L = []
            i = self.i
            while i:
                L.append(int(i & 1L))
                i >>= 1
            L.reverse()
            content = str(L)
        return "%s(%s)" % (self.__class__.__name__, content)

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list