Mam funkcję o nazwie runquery
, która wykonuje wywołania do bazy danych, a następnie generuje wiersze, jeden po drugim. Napisałem dekorator memoize (a dokładniej, ukradłem go po prostu z this stackoverflow question), ale po kolejnych wywołaniach po prostu wydaje pustą sekwencję, prawdopodobnie dlatego, że wartości generatora można uzyskać tylko raz.Czy mogę zapamiętać generator Pythona?
Jak mogę zmodyfikować dekorator zapamiętywania, który działa dla generatorów Pythona? Zdaję sobie sprawę, że w pewnym momencie będę musiał go zapisać w pamięci, ale chciałbym poradzić sobie z tym w dekoratorze i nie modyfikować oryginalnej funkcji.
Obecny kod funkcji memoization jest:
def memoized(f):
# Warning: Doesn't work if f yields values
cache={}
def ret(*args):
if args in cache:
return cache[args]
else:
answer=f(*args)
cache[args]=answer
return answer
return ret
Dzięki za ilustracje! Starałem się zrozumieć sposób użycia 'tee'. __But__ Wydaje mi się, że jest problem podczas sprawdzania instancji: powinieneś przetestować na 'collections.Iterable', ponieważ testowanie z' types.GeneratorType' działa tylko raz: podczas zwracania buforowanego iteratora (obiektu 'iterator.tee') na trzecim. wywołanie funkcji, pamięć podręczna zwróci wyczerpany iterator. –
Masz rację! Jednak testowanie przeciwko 'collections.Iterable 'również byłoby błędne, ponieważ listy i łańcuchy itd. Są również iterable. Zmieniłem zestawy na '(GeneratorType, _tee)', więc działa również dla obiektów tee. – Robin
Tak, to zdecydowanie przesada, ale w Pythonie 2.7 nie ma obiektu '_tee' w' itertools', a funkcja 'itertools.tee' zwraca obiekty' itertools.tee'. Oczywiście nie jest to ich klasa, więc testowanie z 'itertools.tee' nie ma sensu (a także nie działa), stąd moja propozycja z' collections.Iterable'. W jakiej wersji python testowałeś swój kod? –