On Mon, 30 Mar 2009 18:57:01 +0100, <mark.sea...@gmail.com> wrote:

Thanks Scott.  I think you are saying don't try to subclass from type
long, because it is immutable (cannot be changed).  If I subclass from
type object, then the value can be changed, but I still can't print
without explicitely casting back to long in the main routine.  Is this
a catch 22 scenario, or am I just overlooking some method of long to
override to change it's return value?

I'm not sure what you mean by "I still can't print without explicitly
casting back to long in the main routine."  print takes whatever
thing.__str__() gives it (or thing.__repr__() if __str__ doesn't exist).


Here is what I currently have morphed to:

""" Works to change self.val but not self"""

from ctypes import *

class REG_INFO(Structure):
    _fields_ = [
        ('address', c_ubyte),
        ('message', c_char * 256),
        ('size', c_ubyte),
        ('init', c_ulong)
        ]

class BigNumber(long):
    def __new__(class_, init_val, size):
        print 'printing size: %d' % size
        self = long.__new__(class_, init_val)
        self.size = size
        self.val = self
        return self
#
    def __repr__(self):
        print 'from __repr__: %s' % self
        return '%s(%s)' % (type(self).__name__, self)
#
    def __getitem__(self, index): # gets a single bit
        if index >= self.size:
            return self.val

Really?  Surely that can't be sensible behaviour.

        return (self.val >> index) & 1
#
    def __get__(self): # gets a single bit
        return self.val

Fix the comment :-)  A little debugging tells me that this
doesn't get called anyway.

#
    def __setitem__(self,index,value): # sets a single bit
        if index >= self.size:
            self.val = value
            return

Ouch!  No!  This sets the single bit you're asking for,
but wipes out all the others.

        value     = (value&1L)<<index
        mask     = (1L)<<index
        self.val  = (self.val & ~mask) | value
        return
#
    def __int__(self):
        return self.val
#
    def __long__(self):
        return long(self.val)

Hmm.  These don't seem to get called either.  I wonder
where Python's getting the integer value of BigNumber from...
but not enough to go look at the source :-)


class HugeNumber(BigNumber):
    def __new__(class_, reg):
        return BigNumber.__new__(class_, reg.init, reg.size)

[snip tests]

I think you need to get away from the idea that your
register is a number.  It isn't, not really; it's a
sequence of bits which happens to have a number as
a conveniently usable form.  You ought to think about
*not* subclassing from long, but instead overloading
whatever arithmetic operators you want.  You also
ought to think about raising an exception when
__getitem__ or __setitem__ are presented with an index
larger than their size.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to