Re: How do you control _all_ items added to a list?

2005-03-01 Thread Nick Coghlan
Xif wrote:
Overiding all those methods is too much of an effort. I don't really
need them.
Hmm, it might be nice if there was a UserList.ListMixin that was the counterpart 
to UserDict.DictMixin that let's you provide the full dictionary API with just 
__getitem__, __setitem__, __delitem__ and keys()

With an appropriate ListMixin, providing the first three methods would suffice 
to support the full list API.

Cheers,
Nick.
--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
http://boredomandlaziness.skystorm.net
--
http://mail.python.org/mailman/listinfo/python-list


ListMixin (WAS: How do you control _all_ items added to a list?)

2005-03-01 Thread Steven Bethard
Nick Coghlan wrote:
 Hmm, it might be nice if there was a UserList.ListMixin that was the
 counterpart to UserDict.DictMixin
I've thought this occasionally too.  One of the tricky issues though is 
that often you'd like to define __getitem__ for single items and have 
ListMixin add the code for slices.  I haven't figured out how to do this 
cleanly yet...

STeVe
--
http://mail.python.org/mailman/listinfo/python-list


Re: ListMixin (WAS: How do you control _all_ items added to a list?)

2005-03-01 Thread Michael Spencer
Steven Bethard wrote:
Nick Coghlan wrote:
  Hmm, it might be nice if there was a UserList.ListMixin that was the
  counterpart to UserDict.DictMixin
I've thought this occasionally too.  One of the tricky issues though is 
that often you'd like to define __getitem__ for single items and have 
ListMixin add the code for slices.  I haven't figured out how to do this 
cleanly yet...

STeVe
I agree that would be useful.  One solution would be to ask users to implement 
__getsingleitem__ (and not __getitem__) if they want the mixin to handle slice 
logic.  The following illustrates that, and also falls back to slicing the 
iterator if it is provided:

class ProtoListMixin(object):
Prototype ListMixin, exploring slice interface and semantics
def __getitem__(self, index):
if isinstance(index, slice):
start, stop, step = index.start or 0, index.stop, index.step or 1
if start  0 or stop  0 or not stop:
try:
start, stop, step = index.indices(len(self))
except TypeError:
raise TypeError, unsized object
try:
getter = self.__getsingleitem__
return [getter(i) for i in range(start, stop, step)]
except AttributeError:
pass
else:
if index  0:
try:
index = len(self) + index
except TypeError:
raise TypeError, unsized object
try:
return self.__getsingleitem__(index)
except AttributeError:
pass
start, stop, step = index, index + 1, None
# Alternatively, try to use the iterator, if available
import itertools
try:
args = [iter(self)]
except AttributeError:
raise TypeError, Must implement __getsingleitem__ or __iter__
if start:
args.append(start)
args.append(stop)
if step:
if step  1:
raise ValueError, slicing an iterable requires step =1
args.append(step)
iterator = itertools.islice(*args)
if isinstance(index, slice):
return list(iterator)
else:
try:
return iterator.next()
except StopIteration:
raise IndexError, index out of range
# Users should implement __getsingleitem__ for positive indices
class Index(ProtoListMixin):
def __init__(self, data):
For testing, provide a list
self._data = data
def __getsingleitem__(self, index):
return self._data[index]
# If __len__ is implemented, negative indices are supported
class IndexLen(Index):
def __len__(self):
return len(self._data)
# If __getsingleitem__ is not implemented, positive slices are returned
# from an iterator
class Iter(ProtoListMixin):
def __init__(self, data):
For testing, provide an iterable
self._data = data
def __iter__(self):
return iter(self._data)
  a = Index(range(10))
  a[4]
 4
  a[4:8]
 [4, 5, 6, 7]
  a[-4]
 Traceback (most recent call last):
   File input, line 1, in ?
   File ListMixin, line 22, in __getitem__
 TypeError: unsized object
  b = IndexLen(range(10))
  b[-4]
 6
  c = Iter(xrange(10))
  c[3]
 3
  c[3:6]
 [3, 4, 5]
  c[-3]
 Traceback (most recent call last):
   File input, line 1, in ?
   File ListMixin, line 22, in __getitem__
 TypeError: unsized object
 
--
http://mail.python.org/mailman/listinfo/python-list


Re: ListMixin (WAS: How do you control _all_ items added to a list?)

2005-03-01 Thread Raymond Hettinger
[Nick Coghlan]
   Hmm, it might be nice if there was a UserList.ListMixin that was the
   counterpart to UserDict.DictMixin

[Steven Bethard]
 I've thought this occasionally too.  One of the tricky issues though is
 that often you'd like to define __getitem__ for single items and have
 ListMixin add the code for slices.  I haven't figured out how to do this
 cleanly yet...

All that is needed is a helper function and a two line idiom for calling it from
inside __getitem__:

def sliceit(self, sliceobj):
return [self[i] for i in xrange(*sliceobj.indices(len(self)))]

class AlphaList:
def __getitem__(self, i):
if isinstance(i, slice):
return sliceit(self, i)
return chr(i+64)
def __len__(self):
return 26

a = AlphaList()
print a[1], a[2], a[5]
print a[2:5]


-- 
http://mail.python.org/mailman/listinfo/python-list


How do you control _all_ items added to a list?

2005-02-28 Thread Xif
Hi

I want to have control over all items added to a list.

The first attempt was to subclass list and override its .append()
method.

Problem is, there are plenty of other ways the list can have items
added to it - e.g. extend, insert - and theyr'e not at all affected by
the changes I made to append.

Is there some base item-adding method that all other item-adding
methods use, so I can override it and have the changes affect all
item-adding functions?

Thanks,
Xif

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How do you control _all_ items added to a list?

2005-02-28 Thread Fuzzyman

Xif wrote:
 Hi

 I want to have control over all items added to a list.

 The first attempt was to subclass list and override its .append()
 method.

 Problem is, there are plenty of other ways the list can have items
 added to it - e.g. extend, insert - and theyr'e not at all affected
by
 the changes I made to append.

 Is there some base item-adding method that all other item-adding
 methods use, so I can override it and have the changes affect all
 item-adding functions?


If you subclass list then you will need to override all methods that
can set items. This is because the built in methods work directly with
the internal structure and are implemented in C. It's a bit of a
pain... but not that much.

Regards,

Fuzzy
http://www.voidspace.org.uk/python/index.shtml

 Thanks,
 Xif

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How do you control _all_ items added to a list?

2005-02-28 Thread Xif
Quoting Fuzzyman:

If you subclass list then you will need to override all methods that
can set items.


Overiding all those methods is too much of an effort. I don't really
need them.

I'll just have an object that uses a list internally, and define only
the two methods I really need: extend() and getItems().

That way I retain full control over what goes into the private
obj._list, without the superfluous work of overriding all those methods
I don't really need.

Thanks for your help,
Xif

-- 
http://mail.python.org/mailman/listinfo/python-list