Setting "value" of an int-derived class

K

Ken Schutte

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
 
D

Diez B. Roggisch

Ken said:
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?

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
 
S

Sam Pointon

Ken said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top