Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Setting "value" of an int-derived class

7 views
Skip to first unread message

Ken Schutte

unread,
Sep 2, 2006, 7:09:31 PM9/2/06
to pytho...@python.org
Lets say I want an integer class that lets you attach arbitrary
attributes. I can simply do:

class foo(int): pass

x = foo(5)
x.text = "okay"
print x, x.text # prints "5 okay"

So, that's good. But, how can I change the value of x from 5 to
something else, without creating a new instance?

I suppose I could create a function that creates a new "foo" and copies
its attributes, but is there a more direct way? Is the value "5" stored
in some special attribute I can just directly modify?

thanks,
Ken

Diez B. Roggisch

unread,
Sep 2, 2006, 7:23:18 PM9/2/06
to
Ken Schutte schrieb:

You can't do that - the base class is immutable. Subclassing doesn't
change that.

What you can do of course in to create a class foo that will store its
value in an attribute, and overload the arithmetic operators and methods
like __int__, __long__ and __float__.

Diez

Sam Pointon

unread,
Sep 2, 2006, 7:33:44 PM9/2/06
to
Ken Schutte wrote:
> So, that's good. But, how can I change the value of x from 5 to
> something else, without creating a new instance?
>
> I suppose I could create a function that creates a new "foo" and copies
> its attributes, but is there a more direct way? Is the value "5" stored
> in some special attribute I can just directly modify?

In short, no. In long, ints (and longs, for that matter) are immutable
types implemented in a way that Python can't peek at their internals
easily, and so are very resistant to mutability. Imagine the results if
you mutated 5 to 6 or similar; in fact, you don't want regular numbers
to change without some serious hackage.

As for subclasses, a similar thing holds: Python programs can't see the
internal details. Subclasses just forward the method calls like
__add__, __xor__ etc (providing they're not overriden) to the int
class, which in turn pokes around at the C level and returns an answer.

What you probably want is a proxy class, that forwards all number
methods to a wrapped int, and also has a means of setting the wrapped
int. A minimal untested implementation:

class IntWrapper(object):
def __init__(self, num):
self.num = num
def __getattr__(self, attr):
if attr == 'num':
return object.__getattr__(self, 'num')
return getattr(self.num, attr)

Of course, this isn't actually what you asked for, a subclass of int.
But, bar hacking on the C level, which is possible but a bit extreme,
this is the closest thing to a mutable number.

But, personally, I happen to like the memory-wastetastic,
new-instance-returning but functionally purer style. It tends to lead
to less irreplicable bizarre bugs because of objects seemingley
semi-randomly changing state, and Python's garbage collection systems
are fairly good at picking up unused objects. ;)

--Sam

0 new messages