[Fwd: Re: managed lists?]

Larry Bates larry.bates at websafe.com
Tue May 22 10:07:29 EDT 2007


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



More information about the Python-list mailing list