⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 collections.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 4 页
字号:
        setattr(fn, '_sa_instrument_role', 'converter')        return fn    converter = classmethod(converter)    def adds(cls, arg):        """Mark the method as adding an entity to the collection.        Adds "add to collection" handling to the method.  The decorator argument        indicates which method argument holds the SQLAlchemy-relevant value.        Arguments can be specified positionally (i.e. integer) or by name::            @collection.adds(1)            def push(self, item): ...            @collection.adds('entity')            def do_stuff(self, thing, entity=None): ...        """        def decorator(fn):            setattr(fn, '_sa_instrument_before', ('fire_append_event', arg))            return fn        return decorator    adds = classmethod(adds)    def replaces(cls, arg):        """Mark the method as replacing an entity in the collection.        Adds "add to collection" and "remove from collection" handling to        the method.  The decorator argument indicates which method argument        holds the SQLAlchemy-relevant value to be added, and return value, if        any will be considered the value to remove.        Arguments can be specified positionally (i.e. integer) or by name::            @collection.replaces(2)            def __setitem__(self, index, item): ...        """        def decorator(fn):            setattr(fn, '_sa_instrument_before', ('fire_append_event', arg))            setattr(fn, '_sa_instrument_after', 'fire_remove_event')            return fn        return decorator    replaces = classmethod(replaces)    def removes(cls, arg):        """Mark the method as removing an entity in the collection.        Adds "remove from collection" handling to the method.  The decorator        argument indicates which method argument holds the SQLAlchemy-relevant        value to be removed. Arguments can be specified positionally (i.e.        integer) or by name::            @collection.removes(1)            def zap(self, item): ...        For methods where the value to remove is not known at call-time, use        collection.removes_return.        """        def decorator(fn):            setattr(fn, '_sa_instrument_before', ('fire_remove_event', arg))            return fn        return decorator    removes = classmethod(removes)    def removes_return(cls):        """Mark the method as removing an entity in the collection.        Adds "remove from collection" handling to the method.  The return value        of the method, if any, is considered the value to remove.  The method        arguments are not inspected::            @collection.removes_return()            def pop(self): ...        For methods where the value to remove is known at call-time, use        collection.remove.        """        def decorator(fn):            setattr(fn, '_sa_instrument_after', 'fire_remove_event')            return fn        return decorator    removes_return = classmethod(removes_return)# public instrumentation interface for 'internally instrumented'# implementationsdef collection_adapter(collection):    """Fetch the CollectionAdapter for a collection."""    return getattr(collection, '_sa_adapter', None)def collection_iter(collection):    """Iterate over an object supporting the @iterator or __iter__ protocols.    If the collection is an ORM collection, it need not be attached to an    object to be iterable.    """    try:        return getattr(collection, '_sa_iterator',                       getattr(collection, '__iter__'))()    except AttributeError:        raise TypeError("'%s' object is not iterable" %                        type(collection).__name__)class CollectionAdapter(object):    """Bridges between the ORM and arbitrary Python collections.    Proxies base-level collection operations (append, remove, iterate)    to the underlying Python collection, and emits add/remove events for    entities entering or leaving the collection.    The ORM uses an CollectionAdapter exclusively for interaction with    entity collections.    """    def __init__(self, attr, owner_state, data):        self.attr = attr        self._data = weakref.ref(data)        self.owner_state = owner_state        self.link_to_self(data)    data = property(lambda s: s._data(),                    doc="The entity collection being adapted.")    def link_to_self(self, data):        """Link a collection to this adapter, and fire a link event."""        setattr(data, '_sa_adapter', self)        if hasattr(data, '_sa_on_link'):            getattr(data, '_sa_on_link')(self)    def unlink(self, data):        """Unlink a collection from any adapter, and fire a link event."""        setattr(data, '_sa_adapter', None)        if hasattr(data, '_sa_on_link'):            getattr(data, '_sa_on_link')(None)    def adapt_like_to_iterable(self, obj):        """Converts collection-compatible objects to an iterable of values.        Can be passed any type of object, and if the underlying collection        determines that it can be adapted into a stream of values it can        use, returns an iterable of values suitable for append()ing.        This method may raise TypeError or any other suitable exception        if adaptation fails.        If a converter implementation is not supplied on the collection,        a default duck-typing-based implementation is used.        """        converter = getattr(self._data(), '_sa_converter', None)        if converter is not None:            return converter(obj)        setting_type = sautil.duck_type_collection(obj)        receiving_type = sautil.duck_type_collection(self._data())        if obj is None or setting_type != receiving_type:            given = obj is None and 'None' or obj.__class__.__name__            if receiving_type is None:                wanted = self._data().__class__.__name__            else:                wanted = receiving_type.__name__            raise TypeError(                "Incompatible collection type: %s is not %s-like" % (                given, wanted))        # If the object is an adapted collection, return the (iterable) adapter.        if getattr(obj, '_sa_adapter', None) is not None:            return getattr(obj, '_sa_adapter')        elif setting_type == dict:            return getattr(obj, 'itervalues', getattr(obj, 'values'))()        else:            return iter(obj)    def append_with_event(self, item, initiator=None):        """Add an entity to the collection, firing mutation events."""        getattr(self._data(), '_sa_appender')(item, _sa_initiator=initiator)    def append_without_event(self, item):        """Add or restore an entity to the collection, firing no events."""        getattr(self._data(), '_sa_appender')(item, _sa_initiator=False)    def remove_with_event(self, item, initiator=None):        """Remove an entity from the collection, firing mutation events."""        getattr(self._data(), '_sa_remover')(item, _sa_initiator=initiator)    def remove_without_event(self, item):        """Remove an entity from the collection, firing no events."""        getattr(self._data(), '_sa_remover')(item, _sa_initiator=False)    def clear_with_event(self, initiator=None):        """Empty the collection, firing a mutation event for each entity."""        for item in list(self):            self.remove_with_event(item, initiator)    def clear_without_event(self):        """Empty the collection, firing no events."""        for item in list(self):            self.remove_without_event(item)    def __iter__(self):        """Iterate over entities in the collection."""        return getattr(self._data(), '_sa_iterator')()    def __len__(self):        """Count entities in the collection."""        return len(list(getattr(self._data(), '_sa_iterator')()))    def __nonzero__(self):        return True    def fire_append_event(self, item, initiator=None):        """Notify that a entity has entered the collection.        Initiator is the InstrumentedAttribute that initiated the membership        mutation, and should be left as None unless you are passing along        an initiator value from a chained operation.        """        if initiator is not False and item is not None:            self.attr.fire_append_event(self.owner_state, item, initiator)    def fire_remove_event(self, item, initiator=None):        """Notify that a entity has been removed from the collection.        Initiator is the InstrumentedAttribute that initiated the membership        mutation, and should be left as None unless you are passing along        an initiator value from a chained operation.        """        if initiator is not False and item is not None:            self.attr.fire_remove_event(self.owner_state, item, initiator)    def fire_pre_remove_event(self, initiator=None):        """Notify that an entity is about to be removed from the collection.        Only called if the entity cannot be removed after calling        fire_remove_event().        """        self.attr.fire_pre_remove_event(self.owner_state, initiator=initiator)    def __getstate__(self):        return { 'key': self.attr.key,                 'owner_state': self.owner_state,                 'data': self.data }    def __setstate__(self, d):        self.attr = getattr(d['owner_state'].obj().__class__, d['key']).impl        self.owner_state = d['owner_state']        self._data = weakref.ref(d['data'])__instrumentation_mutex = sautil.threading.Lock()def _prepare_instrumentation(factory):    """Prepare a callable for future use as a collection class factory.    Given a collection class factory (either a type or no-arg callable),    return another factory that will produce compatible instances when    called.    This function is responsible for converting collection_class=list    into the run-time behavior of collection_class=InstrumentedList.    """    # Convert a builtin to 'Instrumented*'    if factory in __canned_instrumentation:        factory = __canned_instrumentation[factory]    # Create a specimen    cls = type(factory())    # Did factory callable return a builtin?    if cls in __canned_instrumentation:        # Wrap it so that it returns our 'Instrumented*'        factory = __converting_factory(factory)        cls = factory()    # Instrument the class if needed.    if __instrumentation_mutex.acquire():        try:            if getattr(cls, '_sa_instrumented', None) != id(cls):                _instrument_class(cls)        finally:            __instrumentation_mutex.release()    return factorydef __converting_factory(original_factory):    """Convert the type returned by collection factories on the fly.    Given a collection factory that returns a builtin type (e.g. a list),    return a wrapped function that converts that type to one of our    instrumented types.    """    def wrapper():        collection = original_factory()        type_ = type(collection)        if type_ in __canned_instrumentation:            # return an instrumented type initialized from the factory's            # collection            return __canned_instrumentation[type_](collection)        else:            raise exceptions.InvalidRequestError(                "Collection class factories must produce instances of a "                "single class.")    try:        # often flawed but better than nothing        wrapper.__name__ = "%sWrapper" % original_factory.__name__        wrapper.__doc__ = original_factory.__doc__    except:        pass    return wrapperdef _instrument_class(cls):    """Modify methods in a class and install instrumentation."""    # FIXME: more formally document this as a decoratorless/Python 2.3    # option for specifying instrumentation.  (likely doc'd here in code only,    # not in online docs.)    #    # __instrumentation__ = {    #   'rolename': 'methodname', # ...    #   'methods': {    #     'methodname': ('fire_{append,remove}_event', argspec,    #                    'fire_{append,remove}_event'),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -