Skip to main content
 首页 » 编程设计

python之在 Python 中智能缓存昂贵的对象

2025年05月04日15duanxz

我有一个按顺序排列的图像目录。通常我的代码将使用来自图像的连续子集的数据(例如图像 5-10),访问这些的简单选项是:

  1. 使用在需要时加载图像并读取我的数据(例如像素值)的方法创建包装器对象。这几乎没有内存开销,但会很慢,因为它每次都需要加载每个图像。

  2. 将所有图像存储在内存中。这会很快,但显然我们可以存储多少图像是有限制的。

我想找到:

  • 我可以定义如何读取与索引或路径相对应的图像,然后允许我访问的一些方法,比如 magic_image_collection[index] 而我不必担心它是否是将返回内存中的对象或重新读取它。理想情况下,这会在内存中保留适当的图像或 n 个最近访问的图像。

请您参考如下方法:

您可以扩展默认字典并使用 __missing__ 方法在缺少键的情况下调用加载函数:

class ImageDict(dict): 
    def __missing__(self, key): 
        self[key] = img = self.load(key) 
        return img 
    def load(self, key): 
        # create a queue if not exist (could be moved to __init__) 
        if not hasattr(self, '_queue'): 
            self._queue = [] 
        # pop the oldest entry in the list and the dict 
        if len(self._queue) >= 100: 
            self.pop(self._queue.pop(0)) 
        # append this key as a newest entry in the queue 
        self._queue.append(key) 
        # implement image loading here and return the image instance 
        print 'loading', key 
        return 'Image for %s' % key 

和输出(只有当 key 不存在时才会加载。)

>>> d = ImageDict() 
>>> d[3] 
loading 3 
'Image for 3' 
>>> d[3] 
'Image for 3' 
>>> d['bleh'] 
loading bleh 
'Image for bleh' 
>>> d['bleh'] 
'Image for bleh' 

一种演变是仅存储字典中的最后 N 个元素,并清除最旧的条目。您可以通过保留用于排序的键列表来实现它。