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

Rhodri James rhodri at wildebst.demon.co.uk
Mon Mar 30 20:36:46 EDT 2009


On Mon, 30 Mar 2009 18:57:01 +0100, <mark.seagoe at 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



More information about the Python-list mailing list