added some convenience methods to Jeep
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2109 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
6cfb4c0464
commit
2ab7fc800b
2 changed files with 116 additions and 15 deletions
61
util/jeep.py
61
util/jeep.py
|
@ -31,14 +31,19 @@ class Jeep(object):
|
|||
_attributes = ('_sequence',)
|
||||
|
||||
def __init__(self, seq=[]):
|
||||
sequence = self._sequence = []
|
||||
for item in seq:
|
||||
if isinstance(item, (list, tuple)) and len(item) == 2:
|
||||
attr, value = item
|
||||
sequence.append(attr)
|
||||
object.__setattr__(self, attr, value)
|
||||
else:
|
||||
self.append(item)
|
||||
if isinstance(seq, Jeep):
|
||||
self._sequence = list(seq.keys())
|
||||
for key, value in seq.items():
|
||||
object.__setattr__(self, key, value)
|
||||
else:
|
||||
sequence = self._sequence = []
|
||||
for item in seq:
|
||||
if isinstance(item, (list, tuple)) and len(item) == 2:
|
||||
attr, value = item
|
||||
sequence.append(attr)
|
||||
object.__setattr__(self, attr, value)
|
||||
else:
|
||||
self.append(item)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._sequence)
|
||||
|
@ -75,7 +80,7 @@ class Jeep(object):
|
|||
return getattr(self, key, _notfound) is not _notfound
|
||||
|
||||
def keys(self):
|
||||
return [key for key in self._sequence]
|
||||
return list(self._sequence)
|
||||
|
||||
def values(self):
|
||||
return list(self)
|
||||
|
@ -94,9 +99,6 @@ class Jeep(object):
|
|||
return value
|
||||
return existing
|
||||
|
||||
def index(self, key):
|
||||
return self._sequence.index(key)
|
||||
|
||||
def append(self, obj):
|
||||
self.insert(len(self), obj)
|
||||
|
||||
|
@ -135,9 +137,25 @@ class Jeep(object):
|
|||
def index(self, obj):
|
||||
idx = self.find(obj)
|
||||
if idx < 0:
|
||||
raise ValueError('list.index(x): x not in list')
|
||||
raise ValueError('list.index(x): %r not in list' % obj)
|
||||
return idx
|
||||
|
||||
def remove(self, *keys):
|
||||
myKeys = self.keys()
|
||||
for key in keys:
|
||||
if key in myKeys:
|
||||
del self[key]
|
||||
|
||||
def select(self, *keys):
|
||||
myKeys = self._sequence
|
||||
self._sequence = [k for k in keys if k in myKeys]
|
||||
for k in myKeys:
|
||||
if k not in keys:
|
||||
super(Jeep, self).__delattr__(k)
|
||||
|
||||
def reorder(self, delta, *keys):
|
||||
self._sequence = moveByDelta(self._sequence, keys, delta)
|
||||
|
||||
|
||||
class Term(object):
|
||||
""" A simple name/title association that may be put in a jeep object.
|
||||
|
@ -152,3 +170,20 @@ class Term(object):
|
|||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
def moveByDelta(objs, toMove, delta):
|
||||
""" Return the list given by objs re-ordered in a way that the elements
|
||||
of toMove (which must be in the objs list) have been moved by delta.
|
||||
"""
|
||||
result = [obj for obj in objs if obj not in toMove]
|
||||
if delta < 0:
|
||||
objs = list(reversed(objs))
|
||||
result.reverse()
|
||||
toMove = sorted(toMove, lambda x,y: cmp(objs.index(x), objs.index(y)))
|
||||
for element in toMove:
|
||||
newPos = min(len(result), objs.index(element) + abs(delta))
|
||||
result.insert(newPos, element)
|
||||
if delta < 0:
|
||||
result.reverse()
|
||||
return result
|
||||
|
||||
|
|
|
@ -78,6 +78,25 @@ More Dictionary Methods
|
|||
>>> dict(jeep)
|
||||
{'second': 'new second value', 'third': 'third value', 'first': 'first value'}
|
||||
|
||||
>>> jeep.setdefault('first', 'new first value')
|
||||
'first value'
|
||||
>>> jeep['first']
|
||||
'first value'
|
||||
>>> jeep.setdefault('fourth', 'new fourth value')
|
||||
'new fourth value'
|
||||
>>> jeep['fourth']
|
||||
'new fourth value'
|
||||
>>> len(jeep)
|
||||
4
|
||||
|
||||
>>> del jeep['fourth']
|
||||
>>> len(jeep)
|
||||
3
|
||||
>>> del jeep['fourth']
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: ...not in list
|
||||
|
||||
More Methods and Operators
|
||||
--------------------------
|
||||
|
||||
|
@ -103,7 +122,7 @@ Sequence Additions with Named Objects
|
|||
-------------------------------------
|
||||
|
||||
Objects that have a ``__name__`` attribute can be appended
|
||||
to a Jeep object as the dictionary key can be obtained from these attribute.
|
||||
to a Jeep object as the dictionary key can be obtained from this attribute.
|
||||
|
||||
>>> class Term(object):
|
||||
... def __init__(self, token, title=None, value=None):
|
||||
|
@ -135,7 +154,54 @@ an exception:
|
|||
Constructors
|
||||
------------
|
||||
|
||||
>>> jeep2 = Jeep((('f', '1st'), ('s', '2nd'), ('t', '3rd')))
|
||||
A simple way of creating a Jeep object is using a sequence
|
||||
of key-value pairs.
|
||||
|
||||
>>> jeep2 = Jeep((('1', '1st'), ('2', '2nd'), ('3', '3rd')))
|
||||
>>> list(jeep2)
|
||||
['1st', '2nd', '3rd']
|
||||
|
||||
Using a Jeep object as the argument of the constructor yields a shallow
|
||||
copy.
|
||||
|
||||
>>> jeep3 = Jeep(jeep2)
|
||||
>>> jeep3['1'] is jeep2['1']
|
||||
True
|
||||
>>> jeep3['4'] = '4th'
|
||||
>>> len(jeep3)
|
||||
4
|
||||
>>> len(jeep2)
|
||||
3
|
||||
|
||||
More in-place changes
|
||||
---------------------
|
||||
|
||||
Remove elements in a fault-tolerant way.
|
||||
|
||||
>>> jeep.keys()
|
||||
['first', 'term2', 'second', 'term1']
|
||||
>>> jeep.remove('third', 'second')
|
||||
>>> len(jeep)
|
||||
3
|
||||
>>> jeep.keys()
|
||||
['first', 'term2', 'term1']
|
||||
>>> 'second' in jeep
|
||||
False
|
||||
|
||||
Reorder the sequence and remove all elements that are not
|
||||
in the argument list.
|
||||
|
||||
>>> jeep.select('term1', 'term2', 'nope')
|
||||
>>> jeep.keys()
|
||||
['term1', 'term2']
|
||||
>>> 'first' in jeep
|
||||
False
|
||||
|
||||
You may even reposition a certain element.
|
||||
|
||||
>>> jeep3.keys()
|
||||
['1', '2', '3', '4']
|
||||
>>> jeep3.reorder(-1, '2', '4')
|
||||
>>> jeep3.keys()
|
||||
['2', '1', '4', '3']
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue