[Tutor] __slots__

Liam Clarke ml.cyresse at gmail.com
Fri Oct 14 14:23:04 CEST 2005


> Can't you read the data from the binary file as needed?
> For example build a table of object ids versus file locations
> and then use seek() to go to an object and load it from file
> on demand?
>
> > So, in doing so, I end up with a whole lot of objects, but it's a
> > whole lot of objects I can easily use.
>
> Easy to use but hoggingmemory. If you make the init method
> read the file then instantiating on demand becomes pretty easy too.

Haha, that's pretty danged funny. I just spent ages ripping out all my
file reads on instantiation, so that when a new object was created, it
didn't care where the data came from.... but I'm happy with my
decision to let a function do it for now.

I might just clarify my intent. It's just a library to facilitate
movement of music on/off an iPod without loading up iTunes, or ml_ipod
for Winamp or similar.

So to do that, I've created objects that are just subclassed lists like so -
(they're actually subclasses of a subclass of list, so I've just c & p
ed the inherited bits).

class MHLP(list):
	"""
	Type: Playlist list
	
	Tuple format:
		[0] header_id (4 char string)
		[1] header_length (int)
		[2] number_of_playlists (int) <--(Includes special 'library'
playlist which is hidden)
	
	Note: Library playlist must be first child.
	"""
	
	def __init__(self, data):
		self.extend(data)
		self._setRankAttr()

	def _setRankAttr(self):
		self.isMaster = True
		self.isSlave = True
		self.slaves = []
		self.masters = ['mhsd']

    	def addSlave(self, slave):
		self.slaves.append(slave)

	def writeMe(self, f):
		hexed = struct.pack(self.pattern, self.pData)
		f.write(hexed)
		if self.isMaster:
			for slave in self.slaves:
				slave.writeMe(f)

The setrank part is my way of preserving the hierachy of the file. It
parses the database, and returns a list of objects, which is then
iterated over to set the relationships, via this function -

def setRelationships(headerList):
	masterStack = []
	for dataObject in headerList:
		if dataObject.isSlave:
			while not masterStack[-1][0] in dataObject.masters:
				masterStack.pop()
			
			masterStack[-1].addSlave(dataObject)
					
		if dataObject.isMaster:
			masterStack.append(dataObject)


What happens when a user adds a song to the iPod via this is that the
ID3 tags are read, the song is copied across, and the various MHIT &
MHOD objects created, and appropriate references inserted in the
correct object's slaves list. A Song object is also created just
unifying the methods necessary to add/remove/edit the song's details;
and making available the useful data contained in the fiddlier rawer
objects without exposing the messy internals. A song header is 66
items long, and about 30 of them have unknown function at this point.

When a song is added, a reference to it (an integer, not a Python
reference) needs to be added in about 5/6 objects, plus child counts
need to be updated; hence why holding all the info in memory seemed to
be the simplest solution (for me to develop).

I'm writing for the 80% of cases where at most there'll be 60,000
objects, usually 12,000, and as not overly many people have USB 2.0,
multiple read/writes to the iPod are something I wish to minimise.

Writing to a local drive isn't something I want to rely on either, as
hopefully, I'll be able to get this running directly from the iPod via
a Linux install. Linux can read NTFS but not write it, I believe. I'm
pie in the sky dreaming at the moment, I have to finish adding struct
patterns for the rest of the weird objects.

> Its just the kind of stuff described above. Instead of ac tually
> holding the objects hold a reference to the class and the id(a tuple?),
> then when you actually need the object instantiate it and let the
> constructor fetch the data on demand. That way you only need the
> top level objects in RAM - the current playlist or song selection say..


I must admit, I'm also not too sure about how to maintain the correct
order in a simple manner using that late evaluation stuff; especially
with adding new objects.

I was thinking of perhaps a whole bunch of nested lists, but I don't
tend to do well with nested lists. :/

I suspect I'm getting distracted by premature optimisation, I've been
playing with MPLab's simulator, and trying to write tight ASM is
getting to me. :)

Thank you for your advice.

Regards,

Liam Clarke


More information about the Tutor mailing list