Używałem następującego dekoratora pamięci (z wielkiej książki Python Algorithms: Mastering Basic Algorithms w języku Python ... uwielbiam to, przy okazji).Python - czy ktoś ma dekorator do pamiętania, który poradzi sobie z nieodpartymi argumentami?
def memo(func):
cache = {}
@ wraps(func)
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap
Problem z tym jest to, że dekorator cache słowniku oparte oznacza, że wszystkie moje argumenty muszą być hashable.
Czy ktoś ma implementację (lub modyfikację tego), która dopuszcza niewzruszone argumenty (np. Słowniki)?
Wiem, że brak wartości hash oznacza, że pytanie "czy to w pamięci podręcznej?" staje się nietrywialny, ale pomyślałem, że zapytam.
=== edytowane GIVE KONTEKST ===
pracuję nad funkcją, która zwraca Parnas stylu „używa hierarchii” dane słownikiem module: zależności. Oto konfiguracja:
def uses_hierarchy(requirements):
"""
uses_hierarchy(requirements)
Arguments:
requirements - a dictionary of the form {mod: list of dependencies, }
Return value:
A dictionary of the form {level: list of mods, ...}
Assumptions:
- No cyclical requirements (e.g. if a requires b, b cannot require a).
- Any dependency not listed as a mod assumed to be level 0.
"""
levels = dict([(mod, _level(mod, requirements))
for mod in requirements.iterkeys()])
reversed = dict([(value, []) for value in levels.itervalues()])
for k, v in levels.iteritems():
reversed[v].append(k)
return reversed
def _level(mod, requirements):
if not requirements.has_key(mod):
return 0
dependencies = requirements[mod]
if not dependencies:
return 0
else:
return max([_level(dependency, requirements)
for dependency in dependencies]) + 1
więc, że:
>>> requirements = {'a': [],
... 'b': [],
... 'c': ['a'],
... 'd': ['a','b'],
... 'e': ['c','d'],
... 'f': ['e']
... }
>>> uses_hierarchy(requirements)
{0: ['a', 'b'], 1: ['c', 'd'], 2: ['e'], 3: ['f']}
_level jest funkcja Chcę memoize aby ta konfiguracja bardziej skalowalne. Wdrożone bez memoizacji oblicza poziom zależności wielokrotnie (np. "A" jest obliczane 8 razy, jak sądzę w powyższym przykładzie).
Dzięki,
Mike
Cóż, po prostu je przechowywać w wykazie jako krotek '(args, wynik)' i iteracyjne nad nim. Jak jednak mówisz, nie będzie to szybkie. –
@Thomas K: Pamięć podręczna, która jest wolniejsza, tym więcej rzeczy, które ma, brzmi naprawdę nieproduktywnie. –
@ THC4k: To zależy od tego, czego chcesz. Jeśli masz zamiar uderzać w te same kilka możliwości wiele razy, a funkcja jest dużym obliczeniem lub powolnym żądaniem sieci, może to być więcej niż wystarczająco dobre. A na nowoczesnym komputerze może stać się całkiem duży, zanim stanie się problemem. –