On Mar 30, 9:40 am, Scott David Daniels <scott.dani...@acm.org> wrote: > mark.sea...@gmail.com wrote: > > ... > > It seems like there's no way to do what I'm trying. I am confined to > > Python 2.5.3 for business reasons. > > > So I want a class ShadowRegister, which just has a value that I can do > > get/set bit sel and slice ops. I got that working with __init__. It > > was subclass from "object". Then I wanted a RegisterClass that was a > > subclass of ShadowRegister, which would read a hardware register > > before doing get bit sel/slices, or read HW reg, do set bit sel/slice, > > but when I try to print in hex format ('0x016X') it said it required > > an int (but the ShadowRegister class had no issues). Then I was told > > instead of using object I could subclass as long (seemed the only > > solution for Python 2.5). Then when I started to want to add my own > > init code (like register length in bits), I was told I should use > > __new__ instead of __init__. So but ever since then I've noticed that > > my value is not changing from the initially set value. I'm really > > cornfused now. > > OK, you have asked questions at narrow points about how you can get > whatever is your local problem at the moment, and have received answers > addressing your question. In effect, you've asked 'Which way to the > apothecary?' and 'How do I get around this building' without mentioning > that you're looking for how to get to the top of Everest. Perhaps you > even mentioned your whole goal on your first post, but people see the > questions they see. > > You cannot subclass immutable values to get mutable values; a number > of the properties of immutables are what allows them to participate > in such things as sets and dictionaries. Such things aren't reasonable > for mutable Registers, unless the identity of the register is the thing > that distinguishes it. A set of three Registers, all of which currently > have the value 5 stored in them had better be a 3-element set, or when > you change one of them without changing the other two the size of your > set will have to magically change. > > On a recent job, I was dealing with registers in a device and bit > accesses for reads and writes. I made a pair of classes: One to > correspond to the device itself (with only one instance per chunk of > hardware attached), and another class representing possible values of > the register at given moments. The RegisterValue class was a subclass > of int, and had a from_name class method, mask (&) and set (|) > operations and a repr that show the non-zero bits connected by '|'. > The Register class had read, read_masked, write, and write_masked > operations. It worked quite well. Actually, there were more than > a hundred RegisterValue classes, most of which were subclasses of the > base RegisterValue class with different bit name lists. > > Remember that just because a Register might have a name, doesn't mean > its string representations don't necessarily reflect the contents of > the register (lists show their contents, for example). I think you'll > do better to separate the idea of a register and its contents. > > --Scott David Daniels > scott.dani...@acm.org- Hide quoted text - > > - Show quoted text -
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? 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 return (self.val >> index) & 1 # def __get__(self): # gets a single bit return self.val # def __setitem__(self,index,value): # sets a single bit if index >= self.size: self.val = value return 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) class HugeNumber(BigNumber): def __new__(class_, reg): return BigNumber.__new__(class_, reg.init, reg.size) # my_reg = REG_INFO() my_reg.address = 0xab my_reg.message = 'hello world' my_reg.size = 32 print '\nTEST 1' my_reg.init = 0x55 s = HugeNumber(my_reg) print 'dog = %r = %016X' % (s, s) print '\nTEST 2' my_reg.init = 0x123456789ABCDEF0 bird = HugeNumber(my_reg) print 'type(bird) = %s' % type(bird) print 'bird = 0x%016X' % bird print '\nTEST 3' print 'bird.val = 0x%016X' % bird.val print 'bird = 0x%016X' % bird print 'bird[0] val = 0x%01X' % bird[0] bird[0] = ~bird[0] print 'bird.val = 0x%016X' % bird.val print 'bird = 0x%016X' % bird print 'bird[0] val = 0x%01X' % bird[0] Run it: TEST 1 printing size: 32 from __repr__: 85 dog = HugeNumber(85) = 0000000000000055 TEST 2 printing size: 32 type(bird) = <class '__main__.HugeNumber'> bird = 0x000000009ABCDEF0 TEST 3 bird.val = 0x000000009ABCDEF0 bird = 0x000000009ABCDEF0 bird[0] val = 0x0 bird.val = 0x000000009ABCDEF1 bird = 0x000000009ABCDEF0 <== Value did not change (because immutable I guess) bird[0] val = 0x1 -- http://mail.python.org/mailman/listinfo/python-list