changing value of 'self' when subclassing int

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Coffin

    #1

    changing value of 'self' when subclassing int

    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.

    Thanks for your help,
    David Coffin


    class BitSequence(int ):
    """An integer emulating a sequence of bits, subclassing int."""
    def __new__(cls, value, length=32):
    inst = super(BitSequen ce,cls).__new__ (cls, value)
    inst.length = length
    return inst

    def __setitem__(sel f, index, bit):
    mask = 1 << self.length - index - 1
    if bit == 1:
    # XXX only changing local 'self'
    self |= mask
    elif bit == 0:
    self &= ~mask

    def __getitem__(sel f, i):
    return (self >> (self.length - i -1)) & 1

    def __repr__(self):
    s = ''
    for i in xrange(self.len gth):
    s = str(self >> i & 1) + s
    return s + " : " + str(self)
  • Alex Martelli

    #2
    Re: changing value of 'self' when subclassing int

    David Coffin <dcoffin@gmail. com> wrote:
    [color=blue]
    > I'd like to subclass int to support list access, treating the integer
    > as if it were a list of bits.[/color]

    Fine, but:
    [color=blue]
    > Assigning bits to particular indices involves changing the value of
    > the integer itself, but changing 'self' obviously just alters the[/color]

    ....integers are immutable, like all other numbers in Python: there is NO
    way to "change the value of the integer itself".

    I originally proposed to have "mutable numbers" (at least optionally) in
    gmpy, but the reaction was a broadside against the idea, to the point
    that I never got around to it -- gmpy includes a lot of functionality
    for bit-level manipulation, but still only with immutable bitlists
    (mapped into gmpy.mpz instances).


    Alex

    Comment

    • Fuzzyman

      #3
      Re: changing value of 'self' when subclassing int


      David Coffin wrote:[color=blue]
      > 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.
      >[/color]

      Probably your best bet is to have the assignment done as a method call
      which returns the new value.

      All the best,

      Fuzzyman
      http://www.voidspace.org.uk/python/index.shtml
      [color=blue]
      > Thanks for your help,
      > David Coffin
      >
      >[/color]

      Comment

      • Nick Craig-Wood

        #4
        Re: changing value of 'self' when subclassing int

        David Coffin <dcoffin@gmail. com> wrote:[color=blue]
        > 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.[/color]

        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__(sel f, n):
        return (self.i & self.mask(n)) != 0L
        def __setitem__(sel f, 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@craig-wood.com> -- http://www.craig-wood.com/nick

        Comment

        • David Coffin

          #5
          Re: changing value of 'self' when subclassing int

          Thanks for all the help.
          [color=blue]
          > On 20 Feb 2006, at 17:34, Alex Martelli wrote:
          >
          > ...integers are immutable, like all other numbers in Python: there
          > is NO
          > way to "change the value of the integer itself".[/color]

          So, on learning that I could subclass the number types, I didn't even
          consider the fact that they're immutable. I feel slightly foolish.
          And I'll look at gmpy straight away, it looks like it contains
          functionality I'll find useful.
          [color=blue]
          > On 21 Feb 2006, at 10:58, Fuzzyman wrote:
          >
          > Probably your best bet is to have the assignment done as a method call
          > which returns the new value.[/color]

          I not sure that would be suitable in this case. I'm using genetic
          algorithm code containing some methods that assume 'individuals' are
          represented as bitstrings, and some that assume individuals are
          represented as lists of integers. Ideally, I could have created a
          class for the bitstring individuals that also supported list based
          bit assignment (without too much overhead).

          Best wishes,
          David Coffin

          Comment

          Working...