Sto provando a scrivere una libreria di memoization che utilizza shelve per memorizzare i valori di ritorno in modo persistente. Se ho memorizzato funzioni che chiamano altre funzioni memorizzate, mi chiedo come aprire correttamente il file shelf.È possibile chiamare shelve.open Python in modo annidato?
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()
Solo che questa non funziona
$ 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
Cosa consigliate per una soluzione a questo tipo di problema.
penso che non si dovrebbero avere due puntatori di scrittura aperte allo stesso file .. che quasi certamente porterà ad un comportamento indesiderato ... invece usare 'file.seek (0)', se si vuole tornare all'inizio del un file aperto –
OK, ha senso, ma non voglio tornare all'inizio di alcun file. Io fondamentalmente voglio il secondo 'open' utilizzare il file già aperto del primo, se è già stato aperto, se non poi aprirlo. –
la sua, ovviamente ancora aperta dal momento che sono ancora all'interno del suo blocco contesto a meno che non esplicitamente chiuso da qualche parte –