Jorgen Bodde wrote: > Hi Gabriel, > > Yep that basically covered my implementation as well. It was rather > trivial to make it, and even for a python newbie it was simple which > says enough about the language itself. ;-) > > Although I understand the opinions that you should not care about > types, I do believe putting a constraint on the list by either class > type or interface spec, is no bad thing. The interface specification > is hard to realise as this list now functions as some kind of template > class (hence the parameter that specifies which type is allowed). > > I also added callback arguments that are called opon when there are > items added to the list, deleted or when it is cleared so that the > main object gets notified when another object changes it. > > Here is my implementation (I bet it can be done better, but I am only > playing with python since about 3 months now): > > -------------------------- > > class ObjListException(Exception): > pass > > class ObjListIterator(object): > def __init__(self, objlist): > self.__objlist = objlist > self.__idx = 0 > > > #--------------------------------------------------------------------------- > > def __iter__(self): > return self > > > #--------------------------------------------------------------------------- > > def next(self): > result = None > if self.__idx >= len(self.__objlist): > raise StopIteration() > else: > result = self.__objlist[self.__idx] > self.__idx += 1 > return result > > #=============================================================================== > > > """ ObjList - A managed somewhat strong typed list for Python. > Expects {object}._id to be a property """ > > class ObjList(object): > def __init__(self, class_name, add_callback = None, > remove_callback = None, clear_callback = None): > self.__list = [] > self.__cname = class_name > self.__add_cb = add_callback > self.__remove_cb = remove_callback > self.__clear_cb = clear_callback > > > #--------------------------------------------------------------------------- > > def __iter__(self): > return ObjListIterator(self.unmanaged_list()) > > > #--------------------------------------------------------------------------- > > def __getitem__( self, key): > if key < len(self.__list) and key >= 0: > return self.__list[key] > return None > > > #--------------------------------------------------------------------------- > > def clear(self): > self.__list = [] > > > #--------------------------------------------------------------------------- > > def append(self, obj): > if isinstance(obj, self.__cname): > if obj not in self.__list: > self.__list.append(obj) > if self.__add_cb: > self.__add_cb(self, obj) > else: > raise ObjListException() > > > #--------------------------------------------------------------------------- > > def remove(self, obj): > if obj in self.__list: > self.__list.remove(obj) > if self.__remove_cb: > self.__remove_cb(self, obj) > > > #--------------------------------------------------------------------------- > > def count(self): > return len(self.__list) > > > #--------------------------------------------------------------------------- > > def unmanaged_list(self): > return self.__list[:] > > > #--------------------------------------------------------------------------- > > def find_id(self, id): > for i in self.__list: > if i._id == id: > return i > return None > > > #--------------------------------------------------------------------------- > > def has_item(self, obj): > if obj in self.__list: > return True > return False > > > #--------------------------------------------------------------------------- > > def append_many(self, lst): > for l in lst: > self.append(l) > > Regards, > - Jorgen
IMHO you are trying to write C in Python. In another 3 months I'll bet you will look back on this and say "Why did I bother?". I would suggest that the time to do such "restrictions" would better be spent writing good unit tests for your application. They are what really will assist you in finding those problems way down deep in your code and will be useful for the entire life of the project. You may also want to consider checking to see if the object that is passed in implements the interface that you want instead of requiring that it be a a specific class instance. Something like (not tested): class ObjListIterator(object) # # class variable # __required_methods=['methodname1','methodname2','methodname3'] def chkObjInterface(self, obj): for method in self.__required_methods: if not hasattr(obj, 'methodname1': raise ObjListException("obj must implement '%s' method") else: raise ObjListException("obj must implement 'methodname'" \ "method") return True def append(self, obj): if chkObjInterface(obj): if obj not in self.__list: self.__list.append(obj) if self.__add_cb: self.__add_cb(self, obj) else: raise ObjListException("append.obj must implement 'methodname'" \ method") I would also write append_many as: def extend(self, lst): map(self.append, lst) return I would find it easier to remember extend (since that is very pythonic). If your collection of objects is large, I would also consider putting them in a dictionary instead of a list and indexing them on ID. Hope this helps in some way. -Larry -- http://mail.python.org/mailman/listinfo/python-list