Changeset 1013:9a6c30fec6e1


Ignore:
Timestamp:
Jan 2, 2011, 6:59:50 PM (11 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Message:
Added some docstrings. Improved PEP 8 compliance.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lrucache.py

    r1011 r1013  
    4646from heapq import heappop, heapify
    4747
    48 # the suffix after the hyphen denotes modifications by the
    49 #  ftputil project with respect to the original version
    50 __version__ = "0.2-6"
     48# The suffix after the hyphen denotes modifications by the
     49#  ftputil project with respect to the original version.
     50__version__ = "0.2-7"
    5151__all__ = ['CacheKeyError', 'LRUCache', 'DEFAULT_SIZE']
    5252__docformat__ = 'reStructuredText en'
     
    5555"""Default size of a new LRUCache object, if no 'size' argument is given."""
    5656
     57
    5758class CacheKeyError(KeyError):
    5859    """Error raised when cache requests fail
     
    6061    When a cache record is accessed which no longer exists (or never did),
    6162    this error is raised. To avoid it, you may want to check for the existence
    62     of a cache record before reading or deleting it."""
     63    of a cache record before reading or deleting it.
     64    """
    6365    pass
     66
    6467
    6568class LRUCache(object):
     
    128131                    time.asctime(time.localtime(self.atime)))
    129132
     133
    130134    def __init__(self, size=DEFAULT_SIZE):
     135        """Init the `LRUCache` object. `size` is the initial
     136        _maximum_ size of the cache. The size can be changed by
     137        setting the `size` attribute.
     138        """
    131139        object.__init__(self)
    132140        self.clear()
    133         """Maximum size of the cache.
    134         If more than 'size' elements are added to the cache,
    135         the least-recently-used ones will be discarded."""
    136         # Implicitly check size value.
     141        # Maximum size of the cache.
     142        # If more than 'size' elements are added to the cache,
     143        #  the least-recently-used ones will be discarded.
     144        # This assignment implicitly check the size value.
    137145        self.size = size
    138146        self.__counter = 0
     
    151159
    152160        Cache nodes need a monotonically increasing time indicator.
    153         time.time() and time.clock() don't guarantee this in a
     161        `time.time()` and `time.clock()` don't guarantee this in a
    154162        platform-independent way.
     163
     164        See http://ftputil.sschwarzer.net/trac/ticket/32 for details.
    155165        """
    156166        self.__counter += 1
     
    158168
    159169    def __len__(self):
     170        """Return _current_ number of cache entries.
     171
     172        This may be different from the value of the `size`
     173        attribute.
     174        """
    160175        return len(self.__heap)
    161176
    162177    def __contains__(self, key):
     178        """Return `True` if the item denoted by `key` is in the cache."""
    163179        return self.__dict.has_key(key)
    164180
    165181    def __setitem__(self, key, obj):
     182        """Store item `obj` in the cache under the key `key`.
     183       
     184        If the number of elements after the addition of a new key
     185        would exceed the maximum cache size, the least recently
     186        used item in the cache is "forgotten".
     187        """
    166188        if self.size == 0:
    167             # can't store anything
     189            # Can't store anything.
    168190            return
    169191        if self.__dict.has_key(key):
    170192            node = self.__dict[key]
    171             # update node object in-place
     193            # Update node object in-place.
    172194            node.obj = obj
    173195            node.atime = time.time()
     
    175197            node._sort_key = self._sort_key()
    176198        else:
    177             # size of the heap can be at most the value of
    178             #  self.size because __setattr__ decreases the cache
     199            # The size of the heap can be at most the value of
     200            #  `self.size` because `__setattr__` decreases the cache
    179201            #  size if the new size value is smaller; so we don't
    180             #  need a loop _here_
     202            #  need a loop _here_.
    181203            if len(self.__heap) == self.size:
    182204                heapify(self.__heap)
     
    188210
    189211    def __getitem__(self, key):
     212        """Return the item stored under `key` key.
     213
     214        If no such key is present in the cache, raise a
     215        `CacheKeyError`.
     216        """
    190217        if not self.__dict.has_key(key):
    191218            raise CacheKeyError(key)
    192219        else:
    193220            node = self.__dict[key]
    194             # update node object in-place
     221            # Update node object in-place.
    195222            node.atime = time.time()
    196223            node._sort_key = self._sort_key()
     
    198225
    199226    def __delitem__(self, key):
     227        """Delete the item stored under `key` key.
     228
     229        If no such key is present in the cache, raise a
     230        `CacheKeyError`.
     231        """
    200232        if not self.__dict.has_key(key):
    201233            raise CacheKeyError(key)
     
    207239
    208240    def __iter__(self):
     241        """Iterate over the cache, from the least to the most
     242        recently accessed item.
     243        """
    209244        heapify(self.__heap)
    210245        copy = self.__heap[:]
     
    215250
    216251    def __setattr__(self, name, value):
     252        """If the name of the attribute is "size", set the
     253        _maximum_ size of the cache to the supplied value.
     254        """
    217255        object.__setattr__(self, name, value)
    218         # automagically shrink heap on resize
     256        # Automagically shrink heap on resize.
    219257        if name == 'size':
    220258            size = value
     
    233271    def mtime(self, key):
    234272        """Return the last modification time for the cache record with key.
     273
    235274        May be useful for cache instances where the stored values can get
    236         'stale', such as caching file or network resource contents."""
     275        "stale", such as caching file or network resource contents.
     276        """
    237277        if not self.__dict.has_key(key):
    238278            raise CacheKeyError(key)
     
    241281            return node.mtime
    242282
     283
    243284if __name__ == "__main__":
    244285    cache = LRUCache(25)
Note: See TracChangeset for help on using the changeset viewer.