📄 collections.py
字号:
def clear(fn): def clear(self): for key in self: __del(self, self[key]) fn(self) _tidy(clear) return clear def pop(fn): def pop(self, key, default=Unspecified): if key in self: __del(self, self[key]) if default is Unspecified: return fn(self, key) else: return fn(self, key, default) _tidy(pop) return pop def popitem(fn): def popitem(self): __before_delete(self) item = fn(self) __del(self, item[1]) return item _tidy(popitem) return popitem def setdefault(fn): def setdefault(self, key, default=None): if key not in self: self.__setitem__(key, default) return default else: return self.__getitem__(key) _tidy(setdefault) return setdefault if sys.version_info < (2, 4): def update(fn): def update(self, other): for key in other.keys(): if key not in self or self[key] is not other[key]: self[key] = other[key] _tidy(update) return update else: def update(fn): def update(self, __other=Unspecified, **kw): if __other is not Unspecified: if hasattr(__other, 'keys'): for key in __other.keys(): if key not in self or self[key] is not __other[key]: self[key] = __other[key] else: for key, value in __other: if key not in self or self[key] is not value: self[key] = value for key in kw: if key not in self or self[key] is not kw[key]: self[key] = kw[key] _tidy(update) return update l = locals().copy() l.pop('_tidy') l.pop('Unspecified') return ldef _set_decorators(): """Hand-turned instrumentation wrappers that can decorate any set-like sequence class.""" def _tidy(fn): setattr(fn, '_sa_instrumented', True) fn.__doc__ = getattr(getattr(Set, fn.__name__), '__doc__') Unspecified=object() def add(fn): def add(self, value, _sa_initiator=None): __set(self, value, _sa_initiator) # testlib.pragma exempt:__hash__ fn(self, value) _tidy(add) return add if sys.version_info < (2, 4): def discard(fn): def discard(self, value, _sa_initiator=None): if value in self: self.remove(value, _sa_initiator) _tidy(discard) return discard else: def discard(fn): def discard(self, value, _sa_initiator=None): # testlib.pragma exempt:__hash__ if value in self: __del(self, value, _sa_initiator) # testlib.pragma exempt:__hash__ fn(self, value) _tidy(discard) return discard def remove(fn): def remove(self, value, _sa_initiator=None): # testlib.pragma exempt:__hash__ if value in self: __del(self, value, _sa_initiator) # testlib.pragma exempt:__hash__ fn(self, value) _tidy(remove) return remove def pop(fn): def pop(self): __before_delete(self) item = fn(self) __del(self, item) return item _tidy(pop) return pop def clear(fn): def clear(self): for item in list(self): self.remove(item) _tidy(clear) return clear def update(fn): def update(self, value): for item in value: if item not in self: self.add(item) _tidy(update) return update def __ior__(fn): def __ior__(self, value): if sautil.duck_type_collection(value) is not Set: return NotImplemented for item in value: if item not in self: self.add(item) return self _tidy(__ior__) return __ior__ def difference_update(fn): def difference_update(self, value): for item in value: self.discard(item) _tidy(difference_update) return difference_update def __isub__(fn): def __isub__(self, value): if sautil.duck_type_collection(value) is not Set: return NotImplemented for item in value: self.discard(item) return self _tidy(__isub__) return __isub__ def intersection_update(fn): def intersection_update(self, other): want, have = self.intersection(other), Set(self) remove, add = have - want, want - have for item in remove: self.remove(item) for item in add: self.add(item) _tidy(intersection_update) return intersection_update def __iand__(fn): def __iand__(self, other): if sautil.duck_type_collection(other) is not Set: return NotImplemented want, have = self.intersection(other), Set(self) remove, add = have - want, want - have for item in remove: self.remove(item) for item in add: self.add(item) return self _tidy(__iand__) return __iand__ def symmetric_difference_update(fn): def symmetric_difference_update(self, other): want, have = self.symmetric_difference(other), Set(self) remove, add = have - want, want - have for item in remove: self.remove(item) for item in add: self.add(item) _tidy(symmetric_difference_update) return symmetric_difference_update def __ixor__(fn): def __ixor__(self, other): if sautil.duck_type_collection(other) is not Set: return NotImplemented want, have = self.symmetric_difference(other), Set(self) remove, add = have - want, want - have for item in remove: self.remove(item) for item in add: self.add(item) return self _tidy(__ixor__) return __ixor__ l = locals().copy() l.pop('_tidy') l.pop('Unspecified') return lclass InstrumentedList(list): """An instrumented version of the built-in list.""" __instrumentation__ = { 'appender': 'append', 'remover': 'remove', 'iterator': '__iter__', }class InstrumentedSet(Set): """An instrumented version of the built-in set (or Set).""" __instrumentation__ = { 'appender': 'add', 'remover': 'remove', 'iterator': '__iter__', }class InstrumentedDict(dict): """An instrumented version of the built-in dict.""" __instrumentation__ = { 'iterator': 'itervalues', }__canned_instrumentation = { list: InstrumentedList, Set: InstrumentedSet, dict: InstrumentedDict, }__interfaces = { list: { 'appender': 'append', 'remover': 'remove', 'iterator': '__iter__', '_decorators': _list_decorators(), }, Set: { 'appender': 'add', 'remover': 'remove', 'iterator': '__iter__', '_decorators': _set_decorators(), }, # decorators are required for dicts and object collections. dict: { 'iterator': 'itervalues', '_decorators': _dict_decorators(), }, # < 0.4 compatible naming, deprecated- use decorators instead. None: { } }class MappedCollection(dict): """A basic dictionary-based collection class. Extends dict with the minimal bag semantics that collection classes require. ``set`` and ``remove`` are implemented in terms of a keying function: any callable that takes an object and returns an object for use as a dictionary key. """ def __init__(self, keyfunc): """Create a new collection with keying provided by keyfunc. keyfunc may be any callable any callable that takes an object and returns an object for use as a dictionary key. The keyfunc will be called every time the ORM needs to add a member by value-only (such as when loading instances from the database) or remove a member. The usual cautions about dictionary keying apply- ``keyfunc(object)`` should return the same output for the life of the collection. Keying based on mutable properties can result in unreachable instances "lost" in the collection. """ self.keyfunc = keyfunc def set(self, value, _sa_initiator=None): """Add an item to the collection, with a key provided by this instance's keyfunc.""" key = self.keyfunc(value) self.__setitem__(key, value, _sa_initiator) set = collection.internally_instrumented(set) set = collection.appender(set) def remove(self, value, _sa_initiator=None): """Remove an item from the collection by value, consulting this instance's keyfunc for the key.""" key = self.keyfunc(value) # Let self[key] raise if key is not in this collection if self[key] != value: raise exceptions.InvalidRequestError( "Can not remove '%s': collection holds '%s' for key '%s'. " "Possible cause: is the MappedCollection key function " "based on mutable properties or properties that only obtain " "values after flush?" % (value, self[key], key)) self.__delitem__(key, _sa_initiator) remove = collection.internally_instrumented(remove) remove = collection.remover(remove) def _convert(self, dictlike): """Validate and convert a dict-like object into values for set()ing. This is called behind the scenes when a MappedCollection is replaced entirely by another collection, as in:: myobj.mappedcollection = {'a':obj1, 'b': obj2} # ... Raises a TypeError if the key in any (key, value) pair in the dictlike object does not match the key that this collection's keyfunc would have assigned for that value. """ for incoming_key, value in sautil.dictlike_iteritems(dictlike): new_key = self.keyfunc(value) if incoming_key != new_key: raise TypeError( "Found incompatible key %r for value %r; this collection's " "keying function requires a key of %r for this value." % ( incoming_key, value, new_key)) yield value _convert = collection.converter(_convert)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -