A queue data structure, for string data only, which looks like a File object. This class takes care of the list.append and "".join mess, which is needed for fast string concatenation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
class StringQueue(object): def __init__(self, data=""): self.l_buffer =  self.s_buffer = "" self.write(data) def write(self, data): #check type here, as wrong data type will cause error on self.read, #which may be confusing. if type(data) != type(""): raise TypeError, "argument 1 must be string, not %s" % type(data).__name__ #append data to list, no need to "".join just yet. self.l_buffer.append(data) def _build_str(self): #build a new string out of list new_string = "".join(self.l_buffer) #join string buffer and new string self.s_buffer = "".join((self.s_buffer, new_string)) #clear list self.l_buffer =  def __len__(self): #calculate length without needing to _build_str return sum(len(i) for i in self.l_buffer) + len(self.s_buffer) def read(self, count=None): #if string doesnt have enough chars to satisfy caller, or caller is #requesting all data if count > len(self.s_buffer) or count==None: self._build_str() #if i don't have enough bytes to satisfy caller, return nothing. if count > len(self.s_buffer): return "" #get data requested by caller result = self.s_buffer[:count] #remove requested data from string buffer self.s_buffer = self.s_buffer[len(result):] return result if __name__ == "__main__": sq = StringQueue() sq.write('some data') print sq.read(4) sq.write('_and_some_more_data_!') print sq.read(4) print sq.read()
I use this class to buffer network data as it arrives over a socket. I think it is a little bit smarter than appending to and slicing up a string. The string joining is only performed when the read method call occurs, and when there is not enough string data to satsify the caller.
- I've added a type check to the write method, and now return an empty string from the read method, if there are not enough bytes in the queue to satisfy the caller.
- added __len__ method.