5

Napisałem małą klasę, aby uporczywie zapamiętać niektóre drogie funkcje, które wykonują różne analizy statystyczne losowych sieci.Python: strategie ciągłego zapamiętywania funkcji za pomocą argumentów funkcji?

To są wszystkie czyste funkcje; wszystkie dane są niezmienne. Jednak niektóre funkcje przyjmują funkcje jako argumenty.

Tworzenie kluczy w oparciu o te argumenty jest małym problemem, ponieważ w Pythonie funkcja równości obiektu jest równoważna tożsamości obiektu funkcji, która nie jest zachowywana między sesjami, nawet jeśli implementacja funkcji się nie zmienia.

Na razie hakuję na ten temat, używając nazwy funkcji jako łańcucha znaków, ale to rodzi roje problemów, gdy zaczyna się myśleć o zmianie implementacji funkcji lub anonimowych funkcji i tak dalej. Ale prawdopodobnie nie jestem pierwszym, który martwi się takimi rzeczami.

Czy ktoś ma jakieś strategie do trwałego zapamiętywania funkcji za pomocą argumentów funkcji w Pythonie?

+0

możliwe duplikat [Persistent memoization w Pythonie] (http://stackoverflow.com/questions/9320463/persistent-memoization-in-python) –

+2

@DanatheSane że nie jest duplikatem --- to nie dyskutować uporczywy memoization między wywołaniami, gdzie funkcje są argumentami do zapamiętanej funkcji. – tobyodavies

Odpowiedz

2

Wystarczy popatrzeć na to, jak przy użyciu tożsamości, które należy prawidłowo obsłużyć zmianę wdrożenie w żaden sposób funkcji

[getattr(func.__code__,s) 
for s in ['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 
      'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 
      'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 
      'co_varnames'] 
] 

...

+0

Dzięki. Myślę, że powinieneś zrobić coś takiego, jak powtarzanie nad pamiętanymi funkcjami w 'co_names'. Byłem szczęśliwie zaskoczony, że kod "co_code" był taki sam na wielu różnych platformach i wersjach Pythona w moich początkowych testach. Chyba muszę przeczytać na maszynie wirtualnej Python. –

+0

Czy coś podobnego działa na ogólne obiekty z możliwością wywołania? Chociaż unikanie zanieczyszczeń, takich jak nazwy globalne, jest w porządku, zabronienie używania jakiegokolwiek innego wywołania poza funkcją byłoby niepożądane, jeśli można by mu pomóc. – max

+0

@max nie, nie będzie. Nie można tego zrobić ogólnie, ponieważ to, co stanowi zmianę we wdrażaniu podpory ogólnej, jest definiowane przez klasę tego wywoływanego. Najbliższym, co można mieć nadzieję, jest to, że klasa jest dostępna do wybrania lub marszu, tak, że reprezentacje nie są identyczne między zmianami implementacji. Alternatywnie możesz mieć własny protokół w celu określenia wersji implementacji wywoływacza. – tobyodavies

3

Jedną z opcji byłoby wykorzystanie marshal.dumps(function.func_code)

Spowoduje to utworzenie reprezentacji ciągów dla kodu funkcji. To powinno obsługiwać zmieniające się implementacje i anonimowe funkcje.