============================== Jeep - a General Purpose Class ============================== $Id$ >>> from cybertools.util.jeep import Jeep >>> jeep = Jeep() >>> jeep.first = 'first value' >>> jeep.second = 'second value' >>> jeep.first 'first value' In addition to the usual access via dot notation all attributes can be accessed via dictionary notation: The third type of interface provided by Jeep objects is the sequence or iterator interface. Converting a jeep object to a list iterates over its values (that is different from the dictionary behaviour, but is what you want usually; use the ``.keys()`` method to get at the keys, see below): >>> list(jeep) ['first value', 'second value'] Direct index access to certain entries gives the corresponding value, not the key: >>> jeep[1] 'second value' Changing Jeep Objects --------------------- Assignment by dictionary or attribute access appends the newly assigned attribute: >>> jeep['third'] = 'third value' >>> jeep.third 'third value' >>> list(jeep) ['first value', 'second value', 'third value'] Assigning a new value to an already existing attribute does not change the order but only changes the attribute's value >>> jeep.second = 'new second value' >>> list(jeep) ['first value', 'new second value', 'third value'] >>> jeep[1] 'new second value' More Dictionary Methods ----------------------- >>> jeep.keys() ['first', 'second', 'third'] >>> jeep.values() ['first value', 'new second value', 'third value'] >>> jeep.items() [('first', 'first value'), ('second', 'new second value'), ('third', 'third value')] >>> jeep.get('second') 'new second value' >>> jeep.get('fourth', 'default') 'default' >>> jeep.get('fourth') is None True >>> jeep['fourth'] Traceback (most recent call last): ... KeyError: 'fourth' >>> 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 >>> jeep.update(dict(first='another first value', fifth='5th value')) >>> len(jeep) 5 >>> del jeep['fifth'] >>> len(jeep) 4 >>> del jeep['fifth'] Traceback (most recent call last): ... ValueError: ...not in list More Methods and Operators -------------------------- >>> 'third' in jeep True >>> jeep.pop() 'new fourth value' >>> jeep.pop() 'third value' >>> len(jeep) 2 >>> jeep.pop('blubb') Traceback (most recent call last): ... KeyError: 'blubb' >>> jeep.pop('blubb', None) >>> 'third' in jeep False >>> jeep.index('second') 1 >>> jeep.index('third') Traceback (most recent call last): ... ValueError: ...not in list 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 this attribute. >>> class Term(object): ... def __init__(self, token, title=None, value=None): ... self.__name__ = self.token = token ... self.title = title or token ... self.value = value or title or token >>> t1 = Term('term1', 'title 1') >>> jeep.append(t1) >>> jeep.keys() ['first', 'second', 'term1'] >>> jeep.term1.title 'title 1' >>> jeep.insert(1, Term('term2', 'title 2')) >>> jeep.keys() ['first', 'term2', 'second', 'term1'] >>> jeep[1].title 'title 2' Inserting or appending an object with a name that's already present raises an exception: >>> jeep.append(t1) Traceback (most recent call last): ... ValueError: ...already present Constructors ------------ 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']