Quesion about the proper use of __slots__

Z

Zefria

class Fighter:
.... '''Small one man craft that can only harm other fighters on
their own.'''
.... def __init__(self,statsTuple=(50,5,0,(2,4),1)):
.... self.fuel = statsTuple[0]
.... self.life = statsTuple[1]
.... self.armor = statsTuple[2]
.... self.weapon = statsTuple[3]
.... self.bulk = statsTuple[4]
.... __slots__ =
[self.fuel,self.life,self.armor,self.weapon,self.bulk]
....5

I was reading the special methods, got to slots
(http://docs.python.org/ref/slots.html) and decided that i should use
this to save memory in the program because it'll have to support very
large numbers of fighers at once. It says that once you define slots
then you can't add any variables not listed in slots, but from that
example section I just did, so am I doing something wrong or did I read
it wrong?
 
B

bonono

Zefria said:
... '''Small one man craft that can only harm other fighters on
their own.'''
... def __init__(self,statsTuple=(50,5,0,(2,4),1)):
... self.fuel = statsTuple[0]
... self.life = statsTuple[1]
... self.armor = statsTuple[2]
... self.weapon = statsTuple[3]
... self.bulk = statsTuple[4]
... __slots__ =
[self.fuel,self.life,self.armor,self.weapon,self.bulk]
...5

I was reading the special methods, got to slots
(http://docs.python.org/ref/slots.html) and decided that i should use
this to save memory in the program because it'll have to support very
large numbers of fighers at once. It says that once you define slots
then you can't add any variables not listed in slots, but from that
example section I just did, so am I doing something wrong or did I read
it wrong?

Seems that __slots__ in your case is nothing but a 'local variable' to
the function __init__. I think you need something like this :

class Test(object):
__slots__ = ['attr1','attr2']
 
B

bruno at modulix

Old-style classes are deprecated, use new-style class wherever possible:

class Fighter(object):
....
... '''Small one man craft that can only harm other fighters on
their own.'''
... def __init__(self,statsTuple=(50,5,0,(2,4),1)):
... self.fuel = statsTuple[0]
... self.life = statsTuple[1]
... self.armor = statsTuple[2]
... self.weapon = statsTuple[3]
... self.bulk = statsTuple[4]
... __slots__ =
[self.fuel,self.life,self.armor,self.weapon,self.bulk]
...
(snip)




I was reading the special methods, got to slots
(http://docs.python.org/ref/slots.html) and decided that i should use
this to save memory in the program because it'll have to support very
large numbers of fighers at once.

"premature optimization is the root of all evil".
It says that once you define slots
then you can't add any variables not listed in slots, but from that
example section I just did, so am I doing something wrong or did I read
it wrong?

I think it's:

class Fighter(object):
__slots__ = ['fuel', 'life', 'armor', 'weapon', 'bulk',]
def __init__(self, ...):
# code here
 
Z

Zefria

class Fighter(object):
.... '''Small one man craft that can only harm other fighters on
their own.'''
.... __slots__ = ["fuel","life","armor","weapon","bulk"]
.... def __init__(self,statsTuple=(50,5,0,(2,4),1)):
.... self.fuel = statsTuple[0]
.... self.life = statsTuple[1]
.... self.armor = statsTuple[2]
.... self.weapon = statsTuple[3]
.... self.bulk = statsTuple[4]
....Traceback (most recent call last):

Thank you both, I had tried making it a class variable and didn't see
anything. The trick must have been in making a class that inheriets
from object.

Also, I don't generally do any optimization at all yet (as a highschool
student projects get trashed often enough no to bother over), but in
this special case I'm expecting each "carrier" to have up to 150
fighters, and 3 to 5 carriers for each of the two teams, which comes
out to be quite large.

Additionally, this program's purpose was to experiment with as many of
the special methods as possible, so I suppose I'm on track so far.
 
P

Peter Otten

Zefria said:
Also, I don't generally do any optimization at all yet (as a highschool
student projects get trashed often enough no to bother over), but in
this special case I'm expecting each "carrier" to have up to 150
fighters, and 3 to 5 carriers for each of the two teams, which comes
out to be quite large.

However, 'large numbers' are more likely to start (picture me looking out of
the window) at 100,000 than 10,000 in this context -- and you are at 750...

Peter
 
B

bonono

Peter said:
However, 'large numbers' are more likely to start (picture me looking out of
the window) at 100,000 than 10,000 in this context -- and you are at 750...
He could be working on a machine with < 1M RAM or some other
constraints.
 
M

Marc 'BlackJack' Rintsch

Also, I don't generally do any optimization at all yet (as a highschool
student projects get trashed often enough no to bother over), but in
this special case I'm expecting each "carrier" to have up to 150
fighters, and 3 to 5 carriers for each of the two teams, which comes
out to be quite large.

That's 750 fighter objects. This is not a "large" amount of objects. So
I think it's premature optmization. Especially because you think of using
__slots__ without actually trying if the program uses too much memory.

Ciao,
Marc 'BlackJack' Rintsch
 
Z

Zefria

Well, my computer tends to run at about 497 to 501 out of 504 MB of RAM
used once I start up Gnome, XMMS, and a few Firefox tabs, and I'd
prefer not to see things slipping into Swap space if I can avoid it,
and the fighter data would be only part of a larger program.

And as I said, learning how to use __slots__ is important enough to
hazard a premature guess this time around. If I mess up, the worst that
happens is that I have to write down a new variable name in two places
instead of one now.
 
B

bonono

Zefria said:
Well, my computer tends to run at about 497 to 501 out of 504 MB of RAM
used once I start up Gnome, XMMS, and a few Firefox tabs, and I'd
prefer not to see things slipping into Swap space if I can avoid it,
and the fighter data would be only part of a larger program.

And as I said, learning how to use __slots__ is important enough to
hazard a premature guess this time around. If I mess up, the worst that
happens is that I have to write down a new variable name in two places
instead of one now.

For this particular setup, I don't think it would be a concern given
your mentioned size as you are very unlikely to be actively using all
the apps at the same time and linux is quite efficient in handling it.

However, I don't think attempting to use __slots__ in this case is bad
either. Afterall, one of the strength of python is allowing you to
quickly test out different approachs.
 
P

Peter Otten

For this particular setup, I don't think it would be a concern given
your mentioned size as you are very unlikely to be actively using all
the apps at the same time and linux is quite efficient in handling it.

However, I don't think attempting to use __slots__ in this case is bad
either. Afterall, one of the strength of python is allowing you to
quickly test out different approachs.

Yes, something like

import sys

class Fighter(object):
if "--use-slots" in sys.argv:
__slots__ = [...]


and then comparing

$ python fighters.py

with

$ python fighters.py --use-slots

might be instructive. I don't think the OP will perceive a difference.
He could be working on a machine with < 1M RAM or some other
constraints.

I have 256K, by the way.

Peter
 
S

Steven D'Aprano

... '''Small one man craft that can only harm other fighters on
their own.'''
... __slots__ = ["fuel","life","armor","weapon","bulk"]
... def __init__(self,statsTuple=(50,5,0,(2,4),1)):
... self.fuel = statsTuple[0]
... self.life = statsTuple[1]
... self.armor = statsTuple[2]
... self.weapon = statsTuple[3]
... self.bulk = statsTuple[4]
...Traceback (most recent call last):

Thank you both, I had tried making it a class variable and didn't see
anything. The trick must have been in making a class that inheriets
from object.

For technical reasons, __slots__ don't work as expected for old-style
classes, and never will. You have to inherit from object to make them work
correctly.

Also, I don't generally do any optimization at all yet (as a highschool
student projects get trashed often enough no to bother over), but in
this special case I'm expecting each "carrier" to have up to 150
fighters, and 3 to 5 carriers for each of the two teams, which comes
out to be quite large.

750 objects is not very many, not unless they are carrying around large
chunks of data. And even then, using __slots__ saves only a small
amount of memory per object.

Write your code the slot-less way, see how it performs, and if it is slow,
change your class definition.
 
B

bonono

Peter said:
I have 256K, by the way.
Impressive, curious to know what kind of environment it is as it has
been a long time I have seen such limited spec. My first x86(IBM PC)
had more than that.
 
P

Peter Otten

Impressive, curious to know what kind of environment it is as it has
been a long time I have seen such limited spec. My first x86(IBM PC)
had more than that.

Touché
 
B

bruno at modulix

Zefria said:
Well, my computer tends to run at about 497 to 501 out of 504 MB of RAM
used once I start up Gnome, XMMS, and a few Firefox tabs, and I'd
prefer not to see things slipping into Swap space if I can avoid it,
and the fighter data would be only part of a larger program.

And as I said, learning how to use __slots__ is important enough to
hazard a premature guess this time around. If I mess up, the worst that
happens is that I have to write down a new variable name in two places
instead of one now.

Ok, but don't forget that using slots prevents you from attaching new
attributes on the fly on a given instance - which can be quite handy for
some use cases.
 
S

Steve Holden

Impressive, curious to know what kind of environment it is as it has
been a long time I have seen such limited spec. My first x86(IBM PC)
had more than that.
Yeas, but that's because you are a kid who doesn't remember the
magnificent day when Digital equipment announced their first disk drive
for the PDP-8 series, with aa amazing 64 Kword (96 KB) capacity.

Sheesh, youngsters nowadays ... ;-)

regards
Steve
 
A

Alex Martelli

Zefria said:
this special case I'm expecting each "carrier" to have up to 150
fighters, and 3 to 5 carriers for each of the two teams, which comes
out to be quite large.

The problem with the spread of email is that it reduces the number of
envelopes laying around, and thus makes it harder to do "back of the
envelopes" calculations (the key skill in engineering...).

With 10 carriers between the two teams, and 150 fighters/carrier, you're
dealing with 1500 fighters. If you save 64 bytes per fighter (and I
don't think __slots__ will save quite that much), we're still talking
about less than 100,000 bytes -- peanuts. __slots__ is unwarranted.

Additionally, this program's purpose was to experiment with as many of
the special methods as possible, so I suppose I'm on track so far.

__slots__ is not a method, so it falls outside that purpose as stated.


Alex
 
A

Alex Martelli

Impressive, curious to know what kind of environment it is as it has
been a long time I have seen such limited spec. My first x86(IBM PC)
had more than that.

I believe some cellphones and similarly limited devices may go as low as
256k, but I don't think anybody's running Python today on any device
with less than a MB (and more likely more).

The first PC _I_ owned had 4K of RAM (the cheaper model only had 1K, but
I splurged for the big one) -- Sinclair ZX80. But I didn't run Python
on it (indeed I soon swapped it for one with very similar HW but Forth
instead of Basic, called the "Jupiter Ace": Forth's force has always
been the ability to run with incredibly-little memory).


Alex
 
D

Dennis Lee Bieber

I have 256K, by the way.
Ouch... I pray it is not running some variation of Windows... (My
TRS-80 Model III/4 [upgraded motherboard, same case] had 128K of RAM is
a 32K fixed, and three 32K bank-swapped segment -- in 1982). And I had
512K in my Amiga A-1000.

W98SE was just usable on 256M (of highly expensive RDRAM at the time
-- going from 128M to 256M was $800). On a cold boot I'd have 135K free
(and that was with the vcache limited!)... A little PhotoShop work would
suck up the rest easily. And then... the 64K GDI space would get
trashed...
--
 
P

Peter Otten

Dennis said:
I have 256K, by the way.
Ouch... I pray it is not running some variation of Windows... (My
TRS-80 Model III/4 [upgraded motherboard, same case] had 128K of RAM is
a 32K fixed, and three 32K bank-swapped segment -- in 1982). And I had
512K in my Amiga A-1000.

W98SE was just usable on 256M (of highly expensive RDRAM at the time
-- going from 128M to 256M was $800). On a cold boot I'd have 135K free
(and that was with the vcache limited!)... A little PhotoShop work would
suck up the rest easily. And then... the 64K GDI space would get
trashed...

OK, you all had your laugh now, move on.

Peter, who can't count to 2**you-name-it
 
P

Peter Hansen

Alex said:
The problem with the spread of email is that it reduces the number of
envelopes laying around, and thus makes it harder to do "back of the
envelopes" calculations (the key skill in engineering...).

Actually, a properly performed "engineering approximation" is done
entirely in one's head, preferably without resorting to calculation at
all.

The "back of the envelope" ploy is reserved for cases where one is
trying to impress a waitress (which effort is inevitably doomed to fail
of course), or to make it easier to submit the dinner receipt as a
business expense...

;-)
-Peter
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top