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

mutable ints: I think I have painted myself into a corner

40 views
Skip to first unread message

Cameron Simpson

unread,
May 18, 2013, 8:26:29 PM5/18/13
to pytho...@python.org
TL;DR: I think I want to modify an int value "in place".

Yesterday I was thinking about various "flag set" objects I have
floating around which are essentially bare "object"s whose attributes
I access, for example:

flags = object()
flags.this = True
flags.that = False

and then elsewhere:

if flags.that:
do that ...

Nice and readable, but I thought to myself: so bulky!

The use case for flags is essentially boolean/binary, and so a int
accessed as a bitmask should be smaller.

So I pulled out my BitMask int subclass (which mostly transcribes
the int as "A|B|C" for readability purposes, partly to dillute Nick
Coglan's liking for bulky strings over compact ints on readability
grounds:-), and gave the subclass attribute access.

This works just fine for querying the flags object, with code exactly
like the "if" statement above.

But setting up a flags object? What I _want_ to write is code like this:

Flags = BitMask('this', 'that')

# set default state
flags = Flags()
flags.this = False
flags.that = True
... iterate over some options ...: flags.this = True

and there's my problem. This would modify the int in place. There's
no way to do that. For the base type (int) this makes perfect sense,
as they're immutable.

Before I toss this approach and retreat to my former "object"
technique, does anyone see a way forward to modify an int subclass
instance in place? (That doesn't break math, preferably; I don't
do arithmetic with these things but they are, after all, ints...)

Cheers,
--
Cameron Simpson <c...@zip.com.au>

Why does "philosophy of consciousness/nature of reality" seem to interest you
so much? Take away consciousness and reality and there's not much left.
- Greg Egan, interview in Eidolon 15

Chris Angelico

unread,
May 18, 2013, 9:11:56 PM5/18/13
to pytho...@python.org
On Sun, May 19, 2013 at 10:26 AM, Cameron Simpson <c...@zip.com.au> wrote:
> Before I toss this approach and retreat to my former "object"
> technique, does anyone see a way forward to modify an int subclass
> instance in place? (That doesn't break math, preferably; I don't
> do arithmetic with these things but they are, after all, ints...)
>

Why is it an int subclass? Because there are places where you want to
use it as though it were an int? It might be easier to render those,
instead, eg by creating a __int__ method. (Or is it "an __int__
method"? Not sure.)

ChrisA

Cameron Simpson

unread,
May 18, 2013, 9:54:04 PM5/18/13
to Chris Angelico, pytho...@python.org
I don't want to use it as an int, on the outside. I want to use an
int on the inside as the implementation.

It's an int _subclass_ so that it is no bigger than an int. Otherwise
I may as well just make an ordinary object and be back where I
started. Bulky:-(

The reason it is an _int_ subclass, versus something else, is that
a bitmap is a type of int. So the functional mapping is direct.

I _do_ _not_ want to operate on it from the outside as an int (doing
overt addition, for example, though I can imagine doing bitwise
activities); I want to operate on in _internally_ as a int to decide
what names-by-an-attribute flags are on or off.

So an object with an __int__() method is right out; it's the wrong
interface because it would mean an int() call (possibly implicit)
in exterior code.

Cheers,
--
Cameron Simpson <c...@zip.com.au>

Hoping to shave precious seconds off the time it would take me to get
through the checkout process and on my way home, I opted for the express
line ("9 Items Or Less [sic]" Why nine items? Where do they come up with
these rules, anyway? It's the same way at most stores -- always some
oddball number like that, instead of a more understandable multiple of
five. Like "five.")
- Geoff Miller, geo...@purplehaze.Corp.Sun.COM

Peter Otten

unread,
May 19, 2013, 3:01:49 AM5/19/13
to pytho...@python.org
Cameron Simpson wrote:

> TL;DR: I think I want to modify an int value "in place".
>
> Yesterday I was thinking about various "flag set" objects I have
> floating around which are essentially bare "object"s whose attributes
> I access, for example:
>
> flags = object()
> flags.this = True
> flags.that = False
>
> and then elsewhere:
>
> if flags.that:
> do that ...
>
> Nice and readable, but I thought to myself: so bulky!

Plus, it doesn't work:

>>> object().this = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'this'

> The use case for flags is essentially boolean/binary, and so a int
> accessed as a bitmask should be smaller.
>
> So I pulled out my BitMask int subclass (which mostly transcribes
> the int as "A|B|C" for readability purposes, partly to dillute Nick
> Coglan's liking for bulky strings over compact ints on readability
> grounds:-), and gave the subclass attribute access.
>
> This works just fine for querying the flags object, with code exactly
> like the "if" statement above.
>
> But setting up a flags object? What I _want_ to write is code like this:
>
> Flags = BitMask('this', 'that')
>
> # set default state
> flags = Flags()
> flags.this = False
> flags.that = True
> ... iterate over some options ...: flags.this = True
>
> and there's my problem. This would modify the int in place. There's
> no way to do that. For the base type (int) this makes perfect sense,
> as they're immutable.
>
> Before I toss this approach and retreat to my former "object"
> technique, does anyone see a way forward to modify an int subclass
> instance in place? (That doesn't break math, preferably; I don't
> do arithmetic with these things but they are, after all, ints...)

No, but you could make

flags = Flags(this=False, that=True)

work.

Gregory Ewing

unread,
May 19, 2013, 9:23:28 PM5/19/13
to
Cameron Simpson wrote:
> It's an int _subclass_ so that it is no bigger than an int.

If you use __slots__ to eliminate the overhead of an
instance dict, you'll get an object consisting of a
header plus one reference, which is probably about the
size of an int. But you'll also need an int to put in
that slot, so the total size will be about twice that
of an int.

Another approach would be to subclass array.array and
give instances of it type integer and size 1. Together
with empty __slots__, it will probably be a bit bigger
than an int, but it might still be smaller than a
custom object plus an int.

If all of these are still too big, you might need to
find some way of packing multiple instances into a
single array.array.

--
Greg

Cameron Simpson

unread,
May 20, 2013, 1:57:51 AM5/20/13
to Peter Otten, pytho...@python.org
On 19May2013 09:01, Peter Otten <__pet...@web.de> wrote:
| Cameron Simpson wrote:
|
| > TL;DR: I think I want to modify an int value "in place".
| >
| > Yesterday I was thinking about various "flag set" objects I have
| > floating around which are essentially bare "object"s whose attributes
| > I access, for example:
| >
| > flags = object()
| > flags.this = True
| > flags.that = False
| >
| > and then elsewhere:
| >
| > if flags.that:
| > do that ...
| >
| > Nice and readable, but I thought to myself: so bulky!
|
| Plus, it doesn't work:

Yeah, sorry. My "old" code was a trite subclass of object.
The new broken code is a subclass of int.

| > But setting up a flags object? What I _want_ to write is code like this:
| >
| > Flags = BitMask('this', 'that')
| >
| > # set default state
| > flags = Flags()
| > flags.this = False
| > flags.that = True
| > ... iterate over some options ...: flags.this = True
| >
| > and there's my problem. This would modify the int in place. There's
| > no way to do that. For the base type (int) this makes perfect sense,
| > as they're immutable.
| >
| > Before I toss this approach and retreat to my former "object"
| > technique, does anyone see a way forward to modify an int subclass
| > instance in place? (That doesn't break math, preferably; I don't
| > do arithmetic with these things but they are, after all, ints...)
|
| No, but you could make
|
| flags = Flags(this=False, that=True)

Yes, that is true. Flags would need to be a factory function computing
the corresponding bitmask value and then returning my new int, but
it would work. It still wouldn't let me go the whole way of modifying
the flags after instantiation.

Cheers,
--
Cameron Simpson <c...@zip.com.au>

Carpe Daemon - Seize the Background Process
- Paul Tomblin <ab...@freenet2.carleton.ca>

Cameron Simpson

unread,
May 20, 2013, 2:07:51 AM5/20/13
to Gregory Ewing, pytho...@python.org
On 20May2013 13:23, Greg Ewing <greg....@canterbury.ac.nz> wrote:
| Cameron Simpson wrote:
| >It's an int _subclass_ so that it is no bigger than an int.
|
| If you use __slots__ to eliminate the overhead of an
| instance dict, you'll get an object consisting of a
| header plus one reference, which is probably about the
| size of an int. But you'll also need an int to put in
| that slot, so the total size will be about twice that
| of an int.

Yeah, I was thinking I'd need to go that way. Thanks for the
suggestion.

| Another approach would be to subclass array.array and
| give instances of it type integer and size 1. Together
| with empty __slots__, it will probably be a bit bigger
| than an int, but it might still be smaller than a
| custom object plus an int.

Really? Interesting. I thinik it crosses my "too baroque" threshold,
but maybe not:-)

| If all of these are still too big, you might need to
| find some way of packing multiple instances into a
| single array.array.

Space isn't that real an issue at present; I'll keep that kind of
approach in mind if it comes up. This really came up because I was
feeling that the obvious object-with-boolean-attributes was terrbily
wasteful for something that can be inplemented with a single int,
in principle.

Cheers,
--
Cameron Simpson <c...@zip.com.au>

>>>How do you blip the throttle and wave? Do you blip it real high, then wave
>>>before the revs drop back?
>>Blip = right hand; Wave = left hand. Do both simultaneously. QED.
>Doesnt this make the bike lurch forward thru the intersection?
Not if the disk lock is in place...
- Dean Woodward <de...@agora.rdrop.com>
0 new messages