Serialisasi Python - Mengapa acar?

88

Saya mengerti bahwa pengawetan Python adalah cara untuk 'menyimpan' Objek Python dengan cara yang menghormati pemrograman Object - berbeda dari output yang ditulis dalam file txt atau DB.

Apakah Anda memiliki lebih banyak detail atau referensi tentang poin-poin berikut:

  • di mana benda acar 'disimpan'?
  • mengapa pengawetan mempertahankan representasi objek lebih dari, katakanlah, menyimpan di DB?
  • dapatkah saya mengambil objek acar dari satu sesi shell Python ke yang lain?
  • apakah Anda memiliki contoh signifikan ketika serialisasi berguna?
  • apakah serialisasi dengan acar menyiratkan 'kompresi' data?

Dengan kata lain, saya mencari dokumen tentang pengawetan - Python.doc menjelaskan cara mengimplementasikan acar tetapi tampaknya tidak menyelami detail tentang penggunaan dan perlunya serialisasi.

kiriloff
sumber
Untuk menyimpan status untuk pemulihan nanti atau untuk membagikan / menyalin objek ke runtime python yang berbeda akan menjadi tebakan saya.
synthesizerpatel
13
Banyak dari pertanyaan Anda dijawab oleh artikel Wikipedia tentang serialisasi: en.wikipedia.org/wiki/Serialization
NPE
5
apakah Anda bertanya mengapa saya perlu Pickle untuk serialisasi dengan Python? atau lebih tepatnya apa (tujuan dari) serialisasi? .
moooeeeep
Mungkin bagus untuk menyebutkan masalah keamanan dengan acar. Contohnya dapat ditemukan di dokumen , dan dalam banyak pertanyaan SO, seperti ini .
djvg

Jawaban:

99

Pengawetan adalah cara untuk mengubah objek python (daftar, dikt, dll.) Menjadi aliran karakter. Idenya adalah bahwa aliran karakter ini berisi semua informasi yang diperlukan untuk merekonstruksi objek dalam skrip python lain.

Adapun di mana informasi acar disimpan, biasanya orang akan melakukan:

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

Itu akan menyimpan versi acar dari vardict kami di file 'nama file'. Kemudian, di skrip lain, Anda dapat memuat dari file ini ke dalam variabel dan kamus akan dibuat ulang:

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

Penggunaan lain untuk pengawetan adalah jika Anda perlu mengirimkan kamus ini melalui jaringan (mungkin dengan soket atau sesuatu.) Pertama-tama Anda harus mengubahnya menjadi aliran karakter, kemudian Anda dapat mengirimkannya melalui koneksi soket.

Juga, tidak ada "kompresi" untuk dibicarakan di sini ... ini hanya cara untuk mengubah dari satu representasi (dalam RAM) ke yang lain (dalam "teks").

About.com memiliki pengenalan yang bagus tentang pengawetan di sini .

austin1howard.dll
sumber
2
biasanya orang akan melakukannyawith open('filename') as f: ...
moooeeeep
3
Selain itu, Anda perlu melakukannya with open(filename, 'wb') as f: ...atau Anda tidak akan dapat menulis ke file.
Tim Pietzcker
Terima kasih!! Yang satu ini tentang manajemen ketekunan Python bagus, di sini
kiriloff
1
Secara umum bukanlah ide yang baik untuk menggunakan picklekamus melalui jaringan (json bisa lebih baik di sini). Meskipun dalam kasus yang jarang terjadi, ini mungkin berguna misalnya multiprocessingmodul.
jfs
@ Tim Pietzcker: protocol=0(default pada Python2.x) dapat digunakan dengan file yang dibuka dalam mode teks.
jfs
36

Pengawetan mutlak diperlukan untuk komputasi terdistribusi dan paralel.

Katakanlah Anda ingin melakukan pengurangan peta paralel dengan multiprocessing(atau di seluruh node cluster dengan pyina ), maka Anda perlu memastikan bahwa fungsi yang ingin Anda petakan di seluruh sumber daya paralel akan menjadi acar. Jika tidak menjadi acar, Anda tidak dapat mengirimkannya ke sumber daya lain pada proses lain, komputer, dll. Lihat juga di sini untuk contoh yang baik.

Untuk melakukan ini, saya menggunakan dill , yang dapat membuat serialisasi hampir semua hal dengan python. Dill juga memiliki beberapa alat yang bagus untuk membantu Anda memahami apa yang menyebabkan pengawetan Anda gagal saat kode Anda gagal.

Dan, ya, orang menggunakan picking untuk menyimpan status kalkulasi, atau sesi ipython Anda , atau apa pun. Anda juga dapat memperpanjang Pickler dan UnPickler acar untuk melakukan kompresi dengan bz2atau gzipjika Anda mau.

Mike McKerns
sumber
0

Saya merasa ini sangat berguna dengan kelas khusus yang besar dan kompleks. Dalam contoh tertentu yang saya pikirkan, "Mengumpulkan" informasi (dari database) untuk membuat kelas sudah setengah dari pertempuran. Kemudian informasi yang disimpan di kelas tersebut mungkin diubah pada waktu proses oleh pengguna.

Anda dapat memiliki grup tabel lain di database dan menulis fungsi lain untuk memeriksa semua yang disimpan dan menulisnya ke tabel database baru. Kemudian Anda perlu menulis fungsi lain untuk dapat memuat sesuatu yang disimpan dengan membaca semua info itu kembali.

Alternatifnya, Anda bisa membuat acar seluruh kelas apa adanya dan kemudian menyimpannya ke satu bidang dalam database. Kemudian saat Anda memuatnya kembali, semuanya akan dimuat kembali sekaligus seperti sebelumnya. Ini pada akhirnya dapat menghemat banyak waktu dan kode saat menyimpan dan mengambil kelas yang rumit.

Ayam Max
sumber
-1

ini semacam serialisasi. gunakan cPickle itu jauh lebih cepat daripada acar.

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)
Paritosh Yadav
sumber