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
(e-mail address removed)- 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