Python 如何创建一个变量,其值在文件重新加载期间保持不变?

Python 如何创建一个变量,其值在文件重新加载期间保持不变?,python,python-3.x,persistent-storage,Python,Python 3.x,Persistent Storage,Common Lisp有哪些功能 创建全局变量,但仅在该变量为新变量时设置它:如果它已存在 存在,则不会重置。这在从长时间运行的交互进程重新加载文件时非常有用,因为它保留了数据 我想要Python中的相同版本。 我有一个文件foo.py,其中包含如下内容: cache = {} def expensive(x): try: return cache[x] except KeyError: # do a lot of work cac

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
的值丢失,这是我想要的 避免

如何在
重新加载
中保持
缓存
PS。我想我可以做到:

但出于某种原因,它看起来不像“蟒蛇”。。。 如果是TRT,请告诉我

答复意见:
  • 我对交叉调用持久性不感兴趣;我已经在处理了
  • 我痛苦地意识到重新加载会改变类元对象,我已经在处理了
  • cache
    中的值很大,我不能每次需要它们时都去磁盘

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


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

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

# 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

为什么不使用不同的范围?在
foo,py
中创建一个
get\u cache
函数,并将缓存存储在调用
imp.reload()的同一个文件中。
我想最简单的方法是使用转储json文件这是关键:
如果模块实例化类的实例,重新加载定义类的模块不会影响实例的方法定义-它们继续使用旧的类定义。派生类也是如此。
您在PS中提供的代码看起来绝对应该有效,您试过了吗?重新加载模块时,其字典(包含模块的全局变量)保留。名称的重新定义将覆盖旧定义,因此这通常不是问题。如果模块的新版本未定义由旧版本定义的名称,则旧定义将保留。如果模块维护对象的全局表或缓存,则此功能可发挥模块的优势。”。但无论如何,重新加载可能是个坏主意,如果可以的话,请避免。您可以使用持久存储,也称为文件系统,只需
pickle
变量的内容。我认为
foo_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