【发布时间】:2014-09-16 08:16:03
【问题描述】:
我正在尝试编写一个使用shelve 持久存储返回值的记忆库。如果我有调用其他 memoized 函数的 memoized 函数,我想知道如何正确打开架子文件。
import shelve
import functools
def cache(filename):
def decorating_function(user_function):
def wrapper(*args, **kwds):
key = str(hash(functools._make_key(args, kwds, typed=False)))
with shelve.open(filename, writeback=True) as cache:
if key in cache:
return cache[key]
else:
result = user_function(*args, **kwds)
cache[key] = result
return result
return functools.update_wrapper(wrapper, user_function)
return decorating_function
@cache(filename='cache')
def expensive_calculation():
print('inside function')
return
@cache(filename='cache')
def other_expensive_calculation():
print('outside function')
return expensive_calculation()
other_expensive_calculation()
除非这不起作用
$ python3 shelve_test.py
outside function
Traceback (most recent call last):
File "shelve_test.py", line 33, in <module>
other_expensive_calculation()
File "shelve_test.py", line 13, in wrapper
result = user_function(*args, **kwds)
File "shelve_test.py", line 31, in other_expensive_calculation
return expensive_calculation()
File "shelve_test.py", line 9, in wrapper
with shelve.open(filename, writeback=True) as cache:
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/shelve.py", line 239, in open
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/shelve.py", line 223, in __init__
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/dbm/__init__.py", line 94, in open
return mod.open(file, flag, mode)
_gdbm.error: [Errno 35] Resource temporarily unavailable
您对此类问题的解决方案有何建议。
【问题讨论】:
-
我认为你不应该有两个指向同一个文件的开放写入指针。这几乎肯定会导致不良行为......如果你想回到开头,请使用
file.seek(0)一个打开的文件 -
好的,有道理,但我真的不想回到任何文件的开头。我基本上是想让第二个
open使用第一个已经打开的文件,如果它已经打开,如果没有则打开它。 -
它显然仍处于打开状态,因为您仍在其上下文块中,除非您在某处明确将其关闭
-
@dano 再次更新,带有工作(除了不是)示例
-
鉴于您更新的示例,真正的问题不是“
open是否可以嵌套调用?”,而是“shelve.open以嵌套方式调用?”。
标签: python file-io memoization shelve