Możesz zdecydować i wdrożyć jak każdy rodzaj wcześniej unpicklable dostaje marynowane i unpickled: patrz biblioteki standardowej moduł copy_reg (przemianowany na copyreg
w Pythonie 3. *).
Zasadniczo należy podać funkcję, która, biorąc pod uwagę instancję typu, redukuje ją do krotki - z tym samym protokołem, co metoda specjalna reduce (z tym wyjątkiem, że metoda specjalna zredukowana nie przyjmuje argumentów, ponieważ pod warunkiem, że jest wywołana bezpośrednio na obiekcie, a funkcja, którą podasz, przyjmie obiekt jako jedyny argument).
Zwykle krotka, którą zwrócisz, ma 2 pozycje: wywoływalną i krotkę argumentów do przekazania. Podpowiedź musi być zarejestrowana jako "bezpieczny konstruktor" lub mieć atrybut __safe_for_unpickling__
z wartością rzeczywistą. Te przedmioty będą marynowane, a przy odpalaniu czas wywołania będzie wywoływany z podanymi argumentami i musi zwrócić usunięty obiekt.
Załóżmy na przykład, że chcesz po prostu wybrać moduły po nazwie, aby je rozpakować, oznacza tylko ich ponowne zaimportowanie (np. Załóżmy, że nie zależy ci na dynamicznie modyfikowanych modułach, zagnieżdżonych pakietach itp. zwykłe moduły najwyższego poziomu).Następnie:
>>> import sys, pickle, copy_reg
>>> def savemodule(module):
... return __import__, (module.__name__,)
...
>>> copy_reg.pickle(type(sys), savemodule)
>>> s = pickle.dumps(sys)
>>> s
"c__builtin__\n__import__\np0\n(S'sys'\np1\ntp2\nRp3\n."
>>> z = pickle.loads(s)
>>> z
<module 'sys' (built-in)>
Używam staroświecką formę ASCII zalewy, tak aby s
, łańcuch zawierający marynatę, jest łatwa do zbadania: instruuje unpickling zadzwonić wbudowanej funkcji importu, przy czym ciąg sys
jako jedyny argument. I z
pokazuje, że to faktycznie daje nam z powrotem wbudowany moduł sys
w wyniku rozprysków, zgodnie z potrzebami.
Teraz będziesz musiał sprawić, że rzeczy będą bardziej skomplikowane niż tylko __import__
(będziesz musiał radzić sobie z zapisywaniem i przywracaniem dynamicznych zmian, nawigacją w zagnieżdżonym obszarze nazw itp.), A więc będziesz musiał również zadzwoń pod numer copy_reg.constructor
(przekazując jako argument swoją własną funkcję, która wykonuje tę pracę) przed copy_reg
funkcją oszczędzania modułów, która zwraca twoją drugą funkcję (oraz, jeśli w oddzielnym uruchomieniu, również przed odfukcjonowaniem tych pikli, które zostały wykonane za pomocą tej funkcji). Ale mam nadzieję, że te proste przypadki pomogą pokazać, że nie ma w tym nic naprawdę "skomplikowanego"! -)
Java Beans .. Python Pickles .. Chciałbym zdusić frajerów, którzy wymyślają to Cudowne rzeczy –