„ Програмиране с Python“, ФМИ
Стефан Кънев & Николай Бачийски
11.04.2007г.
Проблем
Имаме нужда да пазим информация между две изпълнения на едно и също приложение. Искаме достъпа до тази информация да е лесен и да добавя минимално код в самото приложение. Нуждите на приложението са прости и няма да имаме нужда от конкурентен достъп или заключване на ресурси.
Решение
Сериализация се нарича възможността да представяме обекти като поредица от байтове. По този начин те могат да бъдат записвани във файловата система или изпращани през TCP/IP и реконструирани в последствие.
Pickle
pickle
е модул, който може да сериализира прости Python обекти.
pickle.dump(object, file)
- Приема отворен за писане файл file и Python обект object. Записва обекта в файла.
pickle.load(object)
- Приема отворен за четене файл и прочита един обект, който е и резултат от функцията
Pickle (2)
from __future__ import with_statement
import pickle
with open('/home/aquarius/foo.txt', 'w') as file:
pickle.dump("The answer", file)
pickle.dump(["spam", "eggs", "ham"], file)
with open('/home/aquarius/foo.txt', 'r') as file:
print pickle.load(file)
print pickle.load(file)
Какво представлява сериализацията?
Pickle
сериализира обектите с един от три различни протокола. Протокола по подразбиране представя обектите като ASCII низове. Функциите dumps
и loads
връщат сериализирана форма вместо да я записват във файл.
import pickle
serializedList = pickle.dumps(["spam", "eggs", "ham"])
print repr(serializedList)
"(lp0\nS'spam'\np1\naS'eggs'\np2\naS'ham'\np3\na."
Какво може да се сериализира?
True
,False
иNone
int
,long
,float
иcomplex
str
иunicode
- Списъци, речници, множества и n-орки, които съдържат само обекти, които могат да се сериализират
- Функции и класове, дефинирани в корена на модула
- Вградени функции, дефинирани в корена на модула
Сериализиране на един обект два пъти
Ако сериализирате сложна структура, в която един обект присъства два пъти (по адрес), pickle
ще го сериализира еднократно.
import pickle
primes = [2, 3, 5, 7, 11, 13]
answer = 42
things = [primes, answer, primes]
print things[0] is things[2] # True
serialized = pickle.dumps(things)
newThings = pickle.loads(serialized)
print newThings[0] is newThings[2] # True
print newThings[0] is things[0] # False
Pickler и Unpickler
Имате достъп до същата функционалност под формата на класове.
from __future__ import with_statement
import pickle
with open('/home/aquarius/foo.txt', 'w') as file:
pickler = pickle.Pickler(file)
pickler.dump('Under the Violet Moon')
pickler.dump('Soldier of Fortune')
pickler.dump('Colubrid on the Tree')
with open('/home/aquarius/foo.txt') as file:
unpickler = pickle.Unpickler(file)
print unpickler.load()
print unpickler.load()
print unpickler.load()
cPickle
cPickle
e реализация на pickle
на C, което я прави доста по-бърза.
from __future__ import with_statement
import cPickle
with open('/home/aquarius/foo.txt', 'w') as file:
cPickle.dump("The answer", file)
cPickle.dump(["spam", "eggs", "ham"], file)
with open('/home/aquarius/foo.txt', 'r') as file:
print cPickle.load(file)
print cPickle.load(file)
cPickle (2)
За сравнение
import pickle
import cPickle
from timeit import Timer
fancy = [[x ** 2 for x in range(0, 1000)], ["spam", "ham", "eggs"],
["-" * i for i in range(0, 1000)],]
def pickleWith(pickler):
serialized = pickler.dumps(fancy)
restored = pickler.loads(serialized)
print "pickle: ", Timer("pickleWith(pickle)", "from __main__ import *").timeit(50)
print "cPickle: ", Timer("pickleWith(cPickle)", "from __main__ import *").timeit(50)
# pickle: 3.28504800797
# cPickle: 0.722439050674
shelve
shelve
е сравнително прост модул, който позволява да записвате данни във файл под формата на речник. Можете да ги достъпвате в последствие по ключовете, с които сте ги записали. Всички обекти се сериализират посредством pickle
, докато организацията им във файла става посредством dbm, gdbm или berkeley db.
shelve (2)
import shelve
db = shelve.open('/home/aquarius/foo.db')
db['name'] = 'Mityo the Python'
db['age'] = 33
db['favouriteBands'] = ["Blackmore's Night", "Deep Purple", "Rainbow"]
db['favouriteSong'] = "Colubrid on the Tree"
db.close()
db = shelve.open('/home/aquarius/foo.db')
print db.keys()
print db['name']
print db['favouriteBands']
print db['favouriteSong']
db.close()
Няма коментари:
Публикуване на коментар