Python serileştirme - Neden turşu?


88

Python dekapajının bir Python Nesnesini Nesne programlamasına uygun bir şekilde 'depolamanın' bir yolu olduğunu anladım - txt dosyası veya DB'de yazılmış bir çıktıdan farklı.

Aşağıdaki noktalarda daha fazla ayrıntı veya referansınız var mı:

  • salamura nesneler nerede 'saklanır'?
  • neden dekapaj nesne temsilini DB'de depolamaktan daha fazla koruyor?
  • Turşu nesneleri bir Python kabuğu oturumundan diğerine geri getirebilir miyim?
  • serileştirmenin yararlı olduğu önemli örnekleriniz var mı?
  • Pickle ile serileştirme veri 'sıkıştırma' anlamına mı geliyor?

Başka bir deyişle, asitleme üzerine bir belge arıyorum - Python.doc turşunun nasıl uygulanacağını açıklıyor ancak serileştirmenin kullanımı ve gerekliliği hakkında ayrıntılara girmiyor gibi görünüyor.


Durumu daha sonra geri yüklemek için kaydetmek veya bir nesneyi farklı bir python çalışma zamanına paylaşmak / kopyalamak benim tahminim olacaktır.
synthesizerpatel

13
Sorularınızın çoğu Wikipedia'nın serileştirme hakkındaki makalesinde yanıtlanıyor: en.wikipedia.org/wiki/Serialization
NPE

5
Python'da serileştirme için neden Pickle'a ihtiyacım olduğunu mu soruyorsun ? veya daha doğrusu serileştirme (amacı) nedir? .
moooeeeep

Turşu ile ilgili güvenlik sorunlarından bahsetmek güzel olabilir. Örnekler bulunabilir dokümanlar ve benzeri sayısız SO sorular, içinde bu bir .
djvg

Yanıtlar:


99

Pickling, bir python nesnesini (liste, dikte vb.) Bir karakter akışına dönüştürmenin bir yoludur. Buradaki fikir, bu karakter akışının, nesneyi başka bir python betiğinde yeniden yapılandırmak için gerekli tüm bilgileri içermesidir.

Turşu bilgisinin nerede saklandığına gelince, genellikle biri şunları yapacaktır:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Bu, diktemizin turşu versiyonunu var'dosya adı' dosyasında saklar . Ardından, başka bir komut dosyasında, bu dosyadan bir değişkene yükleyebilirsiniz ve sözlük yeniden oluşturulur:

with open('filename','rb') as f:
    var = pickle.load(f)

Dekapaj için başka bir kullanım, bu sözlüğü bir ağ üzerinden (belki soketlerle veya başka bir şeyle) iletmeniz gerekiyorsa, önce onu bir karakter akışına dönüştürmeniz, ardından bir soket bağlantısı üzerinden gönderebilirsiniz.

Ayrıca, burada bahsedilecek "sıkıştırma" yoktur ... bu sadece bir gösterimi (RAM'de) diğerine ("metin" olarak) dönüştürmenin bir yoludur.

About.com burada turşuluk için güzel bir giriş sunuyor .


2
genellikle bir yapacağınıwith open('filename') as f: ...
moooeeeep

3
Ayrıca, yapmanız gerekir, yoksa with open(filename, 'wb') as f: ...dosyaya yazamazsınız.
Tim Pietzcker

Teşekkürler!! Python kalıcılık yönetimiyle ilgili olan bu güzel, burada
kiriloff

1
Genel olarak, picklebir sözlüğü ağ üzerinden iletmek için kullanmak pek iyi bir fikir değildir (burada json daha iyi olabilir). Nadir durumlarda, örneğin multiprocessingmodül yararlı olabilir .
jfs

@Tim Pietzcker: protocol=0(Python2.x üzerinde varsayılan) metin modunda açılan dosyalarla kullanılabilir.
jfs

36

Asitleme, dağıtılmış ve paralel hesaplama için kesinlikle gereklidir.

Diyelim ki bir paralel harita-küçültme yapmak istediğinizi varsayalımmultiprocessing (veya pyina ile küme düğümleri arasında ), o zaman paralel kaynaklarda haritalandırmak istediğiniz fonksiyonun pıhtılaşacağından emin olmanız gerekir. Turşu yapmazsa, başka bir işlemdeki, bilgisayardaki vb. Diğer kaynaklara gönderemezsiniz. Ayrıca iyi bir örnek için buraya bakın .

Bunu yapmak için , python'daki hemen hemen her şeyi serileştirebilen dereotu kullanıyorum . Dill , kodunuz başarısız olduğunda dekapaj işleminizin neyin başarısız olmasına neden olduğunu anlamanıza yardımcı olacak bazı iyi araçlara da sahiptir .

Ve evet, insanlar bir hesaplamanın durumunu veya ipython oturumunuzu veya her neyse onu kaydetmek için seçmeyi kullanır . Ayrıca ile sıkıştırma yapmak turşu Pickler ve UnPickler uzatabilir bz2veya gzipeğer isterseniz.


0

Bunu özellikle büyük ve karmaşık özel sınıflarda yararlı buluyorum. Düşündüğüm belirli bir örnekte, sınıfı oluşturmak için bilgileri (bir veritabanından) "toplamak" zaten işin yarısıydı. Daha sonra sınıfta depolanan bu bilgiler, kullanıcı tarafından çalışma zamanında değiştirilebilir.

Veritabanında başka bir tablo grubuna sahip olabilir ve depolanan her şeyi gözden geçirmek ve yeni veritabanı tablolarına yazmak için başka bir işlev yazabilirsiniz. Daha sonra, kaydedilen bir şeyi tüm bu bilgileri tekrar okuyarak yükleyebilmek için başka bir işlev yazmanız gerekir.

Alternatif olarak, tüm sınıfı olduğu gibi seçebilir ve ardından bunu veritabanındaki tek bir alanda depolayabilirsiniz. Sonra onu geri yüklemeye gittiğinizde, hepsi daha önce olduğu gibi aynı anda geri yüklenecektir. Bu, karmaşık sınıfları kaydederken ve alırken çok fazla zaman ve kod tasarrufu sağlayabilir.


-1

bir çeşit serileştirmedir. cPickle kullanın, turşudan çok daha hızlıdır.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.