为什么行缓存检查缓存中元组元素的长度?

时间:2018-06-27 08:18:31

标签: python caching linecache

https://github.com/python/cpython/blob/3.6/Lib/linecache.py中有3个实例

getines

def getlines(filename, module_globals=None):
    if filename in cache:
        entry = cache[filename]
        if len(entry) != 1:
            return cache[filename][2]

updatecache

def updatecache(filename, module_globals=None):
    if filename in cache:
        if len(cache[filename]) != 1:
            del cache[filename]

lazycache

def lazycache(filename, module_globals):
    if filename in cache:
        if len(cache[filename]) == 1:
            return True
        else:
            return False

我正在编写自己的linecache版本,并为此编写测试,我需要了解元组长度可以为1的情况

在一种情况下,执行getlines中的语句。这是第一次访问文件并将其存储在缓存中,然后在第二次访问之前将其删除。但是我仍然不知道为什么其他两个函数中会出现它。

如果有人可以帮助我了解使用此长度检查的目的,这将非常有帮助。

1 个答案:

答案 0 :(得分:1)

查看代码在缓存中存储值的位置。它可以在cache[filename]下存储两种不同的值:

  • 大小,调制时间,行列表和名称(herehere)组成的4元组。
  • 函数的1元组,可按需返回行列表(here)。

1元组用于设置模块的延迟加载。普通文件要延迟加载,只需openread。但是,模块源可能可以从模块的加载程序中找到(可通过导入系统找到),但不能仅通过打开和读取文件(例如zipimport模块)来获得。因此,lazycache必须隐藏加载程序的get_source方法,因此如果以后需要这些行,则可以获取它们。

这意味着,每当使用这些缓存值时,它都必须检查其存储的种类并执行不同的操作。如果它现在需要行,并且有一个懒惰的1元组,则必须去加载这些行(通过updatecache;如果它正在检查高速缓存驱逐并且找到了一个从未被评估过的懒惰的元组,则丢弃它;等等。

还要注意,在updatecache中,如果它是从一个懒惰的1元组加载文件的,则没有调制时间,这意味着在checkcache中,它无法检查是否该文件已过时。但这对于模块源来说是很好的-即使您更改文件,旧版本仍然是import并正在使用的版本。


如果您是从头开始设计的,而不是黑客入侵自1.x早期黑暗时代以来一直存在于stdlib中的内容,则可能会设计出完全不同的产品。例如,您可以使用一个类,也可以使用两个实现相同接口的类。

此外,请注意,linecache中的大量代码都可以用来处理与加载模块源代码有关的特殊情况,除非您试图构建可反映Python代码的内容(例如{{ 1}}),则不需要任何。 (即使您正在执行 ,您可能也想使用traceback模块,而不是直接与导入系统对话。)

因此,inspect可能不是基于自己的行缓存的最佳示例代码。