global name 'self' is not defined - noob trying to learn

mark.seagoe at mark.seagoe at
Mon Mar 30 19:57:01 CEST 2009

On Mar 30, 9:40 am, Scott David Daniels <Scott.Dani... at Acm.Org> wrote:
> mark.sea... at 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... at 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
        value     = (value&1L)<<index
        mask     = (1L)<<index
        self.val  = (self.val & ~mask) | value
    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:

printing size: 32
from __repr__: 85
dog = HugeNumber(85) = 0000000000000055

printing size: 32
type(bird) = <class '__main__.HugeNumber'>
bird = 0x000000009ABCDEF0

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

More information about the Python-list mailing list