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',)
|
_attributes = ('_sequence',)
|
||||||
|
|
||||||
def __init__(self, seq=[]):
|
def __init__(self, seq=[]):
|
||||||
sequence = self._sequence = []
|
if isinstance(seq, Jeep):
|
||||||
for item in seq:
|
self._sequence = list(seq.keys())
|
||||||
if isinstance(item, (list, tuple)) and len(item) == 2:
|
for key, value in seq.items():
|
||||||
attr, value = item
|
object.__setattr__(self, key, value)
|
||||||
sequence.append(attr)
|
else:
|
||||||
object.__setattr__(self, attr, value)
|
sequence = self._sequence = []
|
||||||
else:
|
for item in seq:
|
||||||
self.append(item)
|
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):
|
def __len__(self):
|
||||||
return len(self._sequence)
|
return len(self._sequence)
|
||||||
|
@ -75,7 +80,7 @@ class Jeep(object):
|
||||||
return getattr(self, key, _notfound) is not _notfound
|
return getattr(self, key, _notfound) is not _notfound
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
return [key for key in self._sequence]
|
return list(self._sequence)
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
return list(self)
|
return list(self)
|
||||||
|
@ -94,9 +99,6 @@ class Jeep(object):
|
||||||
return value
|
return value
|
||||||
return existing
|
return existing
|
||||||
|
|
||||||
def index(self, key):
|
|
||||||
return self._sequence.index(key)
|
|
||||||
|
|
||||||
def append(self, obj):
|
def append(self, obj):
|
||||||
self.insert(len(self), obj)
|
self.insert(len(self), obj)
|
||||||
|
|
||||||
|
@ -135,9 +137,25 @@ class Jeep(object):
|
||||||
def index(self, obj):
|
def index(self, obj):
|
||||||
idx = self.find(obj)
|
idx = self.find(obj)
|
||||||
if idx < 0:
|
if idx < 0:
|
||||||
raise ValueError('list.index(x): x not in list')
|
raise ValueError('list.index(x): %r not in list' % obj)
|
||||||
return idx
|
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):
|
class Term(object):
|
||||||
""" A simple name/title association that may be put in a jeep object.
|
""" A simple name/title association that may be put in a jeep object.
|
||||||
|
@ -152,3 +170,20 @@ class Term(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
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)
|
>>> dict(jeep)
|
||||||
{'second': 'new second value', 'third': 'third value', 'first': 'first value'}
|
{'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
|
More Methods and Operators
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
@ -103,7 +122,7 @@ Sequence Additions with Named Objects
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Objects that have a ``__name__`` attribute can be appended
|
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):
|
>>> class Term(object):
|
||||||
... def __init__(self, token, title=None, value=None):
|
... def __init__(self, token, title=None, value=None):
|
||||||
|
@ -135,7 +154,54 @@ an exception:
|
||||||
Constructors
|
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)
|
>>> list(jeep2)
|
||||||
['1st', '2nd', '3rd']
|
['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