在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
中的语句。这是第一次访问文件并将其存储在缓存中,然后在第二次访问之前将其删除。但是我仍然不知道为什么其他两个函数中会出现它。
如果有人可以帮助我了解使用此长度检查的目的,这将非常有帮助。
答案 0 :(得分:1)
查看代码在缓存中存储值的位置。它可以在cache[filename]
下存储两种不同的值:
1元组用于设置模块的延迟加载。普通文件要延迟加载,只需open
和read
。但是,模块源可能可以从模块的加载程序中找到(可通过导入系统找到),但不能仅通过打开和读取文件(例如zipimport
模块)来获得。因此,lazycache
必须隐藏加载程序的get_source
方法,因此如果以后需要这些行,则可以获取它们。
这意味着,每当使用这些缓存值时,它都必须检查其存储的种类并执行不同的操作。如果它现在需要行,并且有一个懒惰的1元组,则必须去加载这些行(通过updatecache
;如果它正在检查高速缓存驱逐并且找到了一个从未被评估过的懒惰的元组,则丢弃它;等等。
还要注意,在updatecache
中,如果它是从一个懒惰的1元组加载文件的,则没有调制时间,这意味着在checkcache
中,它无法检查是否该文件已过时。但这对于模块源来说是很好的-即使您更改文件,旧版本仍然是import
并正在使用的版本。
如果您是从头开始设计的,而不是黑客入侵自1.x早期黑暗时代以来一直存在于stdlib中的内容,则可能会设计出完全不同的产品。例如,您可以使用一个类,也可以使用两个实现相同接口的类。
此外,请注意,linecache
中的大量代码都可以用来处理与加载模块源代码有关的特殊情况,除非您试图构建可反映Python代码的内容(例如{{ 1}}),则不需要任何。 (即使您正在执行 ,您可能也想使用traceback
模块,而不是直接与导入系统对话。)
因此,inspect
可能不是基于自己的行缓存的最佳示例代码。