Python Language
Serialisering av pickle-data
Sök…
Syntax
pickle.dump (objekt, fil, protokoll) # För att serialisera ett objekt
pickle.load (fil) # För att avlägsna serien i ett objekt
pickle.dumps (objekt, protokoll) # För att serialisera ett objekt till byte
pickle.loads (buffert) # För att de-serialzie ett objekt från byte
parametrar
Parameter | detaljer |
---|---|
objekt | Objektet som ska lagras |
fil | Den öppna filen som innehåller objektet |
protokoll | Protokollet som används för att betala objektet (valfri parameter) |
buffert | Ett bytesobjekt som innehåller ett serialiserat objekt |
Anmärkningar
Plockbara typer
Följande objekt är plockbara.
-
None
,True
ochFalse
- siffror (av alla typer)
- strängar (av alla typer)
-
tuple
s,list
s,set
s ochdict
som endast innehåller plockbara objekt - funktioner definierade på toppnivån i en modul
- inbyggda funktioner
- klasser som definieras på den högsta nivån i en modul
- fall av sådana klasser vars
__dict__
eller resultatet av att ringa__getstate__()
är picklable (se de officiella dokumenten för mer information).
- fall av sådana klasser vars
Baserat på den officiella Python-dokumentationen .
pickle
och säkerhet
Pickle-modulen är inte säker . Det ska inte användas när du får seriell information från en opålitlig part, till exempel via Internet.
Använd Pickle för att serialisera och deserialisera ett objekt
pickle
modulen implementerar en algoritm för att förvandla ett godtyckligt Python-objekt till en serie byte. Denna process kallas också att serialisera objektet. Bytströmmen som representerar objektet kan sedan överföras eller lagras och senare rekonstrueras för att skapa ett nytt objekt med samma egenskaper.
För den enklaste koden använder vi funktionerna dump()
och load()
.
För att serialisera objektet
import pickle
# An arbitrary collection of objects supported by pickle.
data = {
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': {None, True, False}
}
with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
Att deserialisera objektet
import pickle
with open('data.pickle', 'rb') as f:
# The protocol version used is detected automatically, so we do not
# have to specify it.
data = pickle.load(f)
Använda pickle- och byteobjekt
Det är också möjligt att serialisera in och deserialisera ur byteobjekt med hjälp av funktionen dumps
och loads
, vilket motsvarar dump
och load
.
serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
# type(serialized_data) is bytes
deserialized_data = pickle.loads(serialized_data)
# deserialized_data == data
Anpassa inlagda data
Vissa data kan inte betas. Andra uppgifter bör inte betas av andra skäl.
Vad som kommer att betas kan definieras i __getstate__
metoden. Denna metod måste returnera något som är picklable.
På den motsatta sidan är __setstate__
: den får det __getstate__
skapade och måste initialisera objektet.
class A(object):
def __init__(self, important_data):
self.important_data = important_data
# Add data which cannot be pickled:
self.func = lambda: 7
# Add data which should never be pickled, because it expires quickly:
self.is_up_to_date = False
def __getstate__(self):
return [self.important_data] # only this is needed
def __setstate__(self, state):
self.important_data = state[0]
self.func = lambda: 7 # just some hard-coded unpicklable function
self.is_up_to_date = False # even if it was before pickling
Nu kan detta göras:
>>> a1 = A('very important')
>>>
>>> s = pickle.dumps(a1) # calls a1.__getstate__()
>>>
>>> a2 = pickle.loads(s) # calls a1.__setstate__(['very important'])
>>> a2
<__main__.A object at 0x0000000002742470>
>>> a2.important_data
'very important'
>>> a2.func()
7
Implementeringen här pikar en lista med ett värde: [self.important_data]
. Det var bara ett exempel, __getstate__
kunde ha returnerat allt som är plockbart, så länge __setstate__
vet hur man gör motmannen. Ett bra alternativ är en ordlista med alla värden: {'important_data': self.important_data}
.
Konstruktör kallas inte! Observera att i det föregående exemplet skapades a2
i pickle.loads
utan att någonsin ringa A.__init__
, så A.__setstate__
tvungen att initialisera allt som __init__
skulle ha initialiserat om det kallades.