> On 14/09/12 22:16, Albert-Jan Roskam wrote: >> Hi, >> >> I defined a __getitem__ special method in a class that reads a binary data >> file using a C library. The docstring should clarify the purpose of the >> method. This works exactly as I intended it, however, the "key" > argument is >> actually used as an index (it also raises an IndexError when<key> is >> greater than the number of records in the file). Am I abusing the > __getitem__ >> method, or is this just a creative way of using it? > > No, that's exactly what __getitem__ is for. It does double-duty for > key-lookup > in mappings (dict[key]) and index-lookup in sequences (list[index]). > > You can also support ranges of indexes by accepting a slice argument.
COOL! I was already wondering how this could be implemented. Dive into Python is pretty exhaustive wrt special methods, but I don't think they mentioned using the slice class. Below is how I did it. Is it recommended to define the geitem() function inside the __getitem__() method? I was thinking I could also define a _getitem() private method. Hmmm, maybe getitem() is redefined over and over again the way I did it now? def __getitem__(self, key): """ This function reports the record of case number <key>. For example: firstRecord = SavReader(savFileName)[0] """ def getitem(key): retcode1 = self.iomodule.SeekNextCase(self.fh, ctypes.c_long(int(key))) self.caseBuffer, self.caseBufferPtr = self.getCaseBuffer() retcode2 = self.iomodule.WholeCaseIn(self.fh, self.caseBufferPtr) record = struct.unpack(self.structFmt, self.caseBuffer.raw) if any([retcode1, retcode2]): raise RuntimeError, "Error retrieving record %d [%s, %s]" % \ (key, retcodes[retcode1], retcodes[retcode2]) return record if isinstance(key, slice): records = [getitem(i) for i in range(*key.indices(self.nCases))] return records elif hasattr(key, "__int__"): # isinstance(key, (int, float)): if abs(key) > (self.nCases - 1): raise IndexError else: key = self.nCases + key if key < 0 else key record = getitem(key) return record else: raise TypeError > Another comment below: > > >> # Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit > (Intel)] on win32 >> >> def __getitem__(self, key): >> """ This function reports the record of case > number<key>. >> For example: firstRecord = FileReader(fileName)[0] > """ >> if not isinstance(key, (int, float)): >> raise TypeError > > Floats? Do you actually have have case number (for example) > 0.14285714285714285 ? > > For this case, I think it is reasonable to insist on exactly an int, > and nothing else (except possibly a slice object, to support for > example obj[2:15]). > I also accepted floats as a convenience. I had examples in mind like: record = data[1.0] . Kind of annoying when this raises a TypeError. But in your example makes perfect sense to raise such an exception. Eryksun, Steven: Thanks!!! Albert-Jan _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor