如何创建一个变量,它的值在文件重新加载时保持不变?

2024-04-17 00:01:44 发布

您现在位置:Python中文网/ 问答频道 /正文

Common Lisp有^{},其中 创建一个全局变量,但仅当它是新变量时设置它:如果它已经存在 存在,它是而不是重置。这在从长时间运行的交互进程重新加载文件时非常有用,因为它保留了数据。你知道吗

我想在Python里也一样。 我有一个文件foo.py,它包含如下内容:

cache = {}
def expensive(x):
    try:
        return cache[x]
    except KeyError:
        # do a lot of work
        cache[x] = res
        return res

当我做^{}时,cache的值丢失了,这是我想要的 避免。你知道吗

如何保持cachereload之间?你知道吗

PS。我想我可以跟着How do I check if a variable exists?

if 'cache' not in globals():
   cache = {}

但由于某种原因它看起来不像是“Python”。。。 如果TRT,请告诉我!你知道吗

回答意见:

  • 我对交叉调用持久性不感兴趣;我已经在处理这个问题了。你知道吗
  • 我痛苦地意识到重新加载会改变类元对象,我已经在处理了。你知道吗
  • cache中的值非常大,我不能每次需要它们时都去磁盘。你知道吗

Tags: 文件数据pycache内容returniffoo
2条回答

这里有几个选择。一种是使用临时文件作为缓存的持久存储,并在每次加载模块时尝试加载:

# foo.py
import tempfile
import pathlib
import pickle

_CACHE_TEMP_FILE_NAME = '__foo_cache__.pickle'
_CACHE = {}

def expensive(x):
    try:
        return _CACHE[x]
    except KeyError:
        # do a lot of work
        _CACHE[x] = res
        _save_cache()
        return res

def _save_cache():
    tmp = pathlib.Path(tempfile.gettempdir(), _CACHE_TEMP_FILE_NAME)
    with tmp.open('wb') as f:
        pickle.dump(_CACHE, f)

def _load_cache():
    global _CACHE
    tmp = pathlib.Path(tempfile.gettempdir(), _CACHE_TEMP_FILE_NAME)
    if not tmp.is_file():
        return
    try:
        with tmp.open('rb') as f:
            _CACHE = pickle.load(f)
    except pickle.UnpicklingError:
        pass

_load_cache()

唯一的问题是,您需要相信环境不会编写任何恶意文件来代替临时文件(对于错误或恶意构造的数据,pickle模块是不安全的)。你知道吗

另一种选择是为缓存使用另一个不会重新加载的模块:

# foo_cache.py
Cache = {}

然后:

# foo.py
import foo_cache

def expensive(x):
    try:
        return foo_cache.Cache[x]
    except KeyError:
        # do a lot of work
        foo_cache.Cache[x] = res
        return res

由于重新加载的全部目的是确保已执行模块的代码再次运行,因此根本无法避免某种“重新加载检测”

您使用的代码似乎是您参考的问题中给出的最佳答案。你知道吗

相关问题 更多 >