Bagaimana Anda menambahkan data biner di python menggunakan acar?

Tulis program berbasis menu dengan Python yang meminta pengguna untuk menambah, menampilkan, dan mencari catatan karyawan yang disimpan dalam file biner. Catatan karyawan berisi kode karyawan, nama dan gaji. Itu harus disimpan dalam objek daftar. Program Anda harus mengambil objek dan menyimpannya ke file biner

Show

Serialisasi (Juga disebut Pickling). Proses mengubah hierarki objek Python menjadi aliran byte sehingga dapat ditulis ke dalam file

De-Serialisasi (Juga disebut Unpickling). Kebalikan dari Pickling di mana aliran byte diubah menjadi hierarki objek. Unpickling menghasilkan salinan yang tepat dari objek asli

  1. Modul acar impor pertama
  2. Gunakan metode dump() dan load() dari modul pickle untuk melakukan operasi baca dan tulis pada file biner

Mode Pembukaan File

tulisan wb saja. Menimpa file biner jika ada. Jika tidak, buat file biner baru untuk ditulis

wb+ baik menulis maupun membaca. Menimpa file biner jika ada. Jika tidak, buat file biner baru untuk ditulis

rb hanya membaca. Menetapkan penunjuk file di awal file biner

rb+ baik membaca maupun menulis. Menetapkan penunjuk file di awal file biner

ab untuk menambahkan. Pindahkan penunjuk file di akhir file biner. Membuat file baru untuk menulis, jika tidak ada

ab+ untuk menambahkan dan membaca. Pindahkan penunjuk file di akhir. Jika file biner tidak ada, itu membuat file baru untuk membaca dan menulis

  1. Menulis ke File Biner. Pengawetan

Keluaran

2. Tulis program untuk membuka file EMP. dat(Dibuat di program sebelumnya), baca objek yang tertulis di dalamnya dan tampilkan

Keluaran

3. Tulis program untuk menambahkan dua catatan karyawan ke file yang dibuat di program sebelumnya dengan mendapatkan data dari pengguna

Keluaran

Mengakses dan memanipulasi lokasi penunjuk file

Python menyediakan dua fungsi untuk memanipulasi posisi pointer file dan dengan demikian pengguna dapat membaca dan menulis dari posisi yang diinginkan

Fungsi beri tahu ( ).

Fungsi tell() mengembalikan posisi penunjuk file saat ini di dalam file

. memberi tahu( )

Fungsi mencari ( ).

Fungsi seek ( ) mengubah posisi penunjuk file dengan menempatkan penunjuk file pada posisi yang ditentukan dalam file terbuka

. mencari(offset[,mode])

Di mana

offset =======>adalah angka yang menentukan jumlah byte

modus =======> adalah angka 0 atau 1 atau 2

0 untuk awal file

1 posisi penunjuk file saat ini

2 akhir file

4. Tulis program untuk membuka file EMP. dat(Dibuat di program sebelumnya), baca dan ubah nama empno1207 menjadi vijay7 baru dan tampilkan

Modul mengimplementasikan protokol biner untuk serialisasi dan de-serialisasi struktur objek Python. "Pickling" adalah proses di mana hierarki objek Python diubah menjadi aliran byte, dan "unpickling" adalah operasi kebalikannya, di mana aliran byte (dari a atau ) diubah kembali menjadi hierarki objek. Pengawetan (dan penghilangan pengawetan) secara alternatif dikenal sebagai "serialisasi", "penataan", atau "perataan";

Peringatan

Modul

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
7 tidak aman. Hapus hanya data yang Anda percayai

Dimungkinkan untuk membangun data acar berbahaya yang akan mengeksekusi kode arbitrer selama unpickling. Jangan pernah membongkar data yang mungkin berasal dari sumber yang tidak tepercaya, atau yang mungkin telah dirusak

Pertimbangkan untuk menandatangani data dengan jika Anda perlu memastikan bahwa itu belum dirusak

Format serialisasi yang lebih aman seperti mungkin lebih sesuai jika Anda memproses data yang tidak tepercaya. Melihat

Hubungan dengan modul Python lainnya

Perbandingan dengan # Simple example presenting how persistent ID can be used to pickle # external objects by reference. import pickle import sqlite3 from collections import namedtuple # Simple class representing a record in our database. MemoRecord = namedtuple("MemoRecord", "key, task") class DBPickler(pickle.Pickler): def persistent_id(self, obj): # Instead of pickling MemoRecord as a regular class instance, we emit a # persistent ID. if isinstance(obj, MemoRecord): # Here, our persistent ID is simply a tuple, containing a tag and a # key, which refers to a specific record in the database. return ("MemoRecord", obj.key) else: # If obj does not have a persistent ID, return None. This means obj # needs to be pickled as usual. return None class DBUnpickler(pickle.Unpickler): def __init__(self, file, connection): super().__init__(file) self.connection = connection def persistent_load(self, pid): # This method is invoked whenever a persistent ID is encountered. # Here, pid is the tuple returned by DBPickler. cursor = self.connection.cursor() type_tag, key_id = pid if type_tag == "MemoRecord": # Fetch the referenced record from the database and return it. cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),)) key, task = cursor.fetchone() return MemoRecord(key, task) else: # Always raises an error if you cannot return the correct object. # Otherwise, the unpickler will think None is the object referenced # by the persistent ID. raise pickle.UnpicklingError("unsupported persistent object") def main(): import io import pprint # Initialize and populate our database. conn = sqlite3.connect(":memory:") cursor = conn.cursor() cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)") tasks = ( 'give food to fish', 'prepare group meeting', 'fight with a zebra', ) for task in tasks: cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,)) # Fetch the records to be pickled. cursor.execute("SELECT * FROM memos") memos = [MemoRecord(key, task) for key, task in cursor] # Save the records using our custom DBPickler. file = io.BytesIO() DBPickler(file).dump(memos) print("Pickled records:") pprint.pprint(memos) # Update a record, just for good measure. cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1") # Load the records from the pickle data stream. file.seek(0) memos = DBUnpickler(file, conn).load() print("Unpickled records:") pprint.pprint(memos) if __name__ == '__main__': main() _2

Python memiliki modul serialisasi yang lebih primitif yang disebut , tetapi secara umum harus selalu menjadi cara yang disukai untuk membuat serialisasi objek Python. ada terutama untuk mendukung file

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_6 Python

Modul ini berbeda dari beberapa cara yang signifikan

  • Modul melacak objek yang telah diserialkan, sehingga referensi selanjutnya ke objek yang sama tidak akan diserialkan lagi. tidak melakukan ini

    Ini memiliki implikasi baik untuk objek rekursif dan berbagi objek. Objek rekursif adalah objek yang berisi referensi ke dirinya sendiri. Ini tidak ditangani oleh marshal, dan pada kenyataannya, mencoba menyusun objek rekursif akan membuat juru bahasa Python Anda crash. Berbagi objek terjadi ketika ada beberapa referensi ke objek yang sama di tempat yang berbeda dalam hierarki objek yang diserialisasi. menyimpan objek semacam itu hanya sekali, dan memastikan bahwa semua referensi lainnya mengarah ke salinan master. Objek yang dibagikan tetap dibagikan, yang bisa sangat penting untuk objek yang bisa berubah

  • tidak dapat digunakan untuk membuat serialisasi kelas yang ditentukan pengguna dan instansnya. dapat menyimpan dan memulihkan instance kelas secara transparan, namun definisi kelas harus dapat diimpor dan berada dalam modul yang sama seperti saat objek disimpan

  • Format serialisasi tidak dijamin portabel di seluruh versi Python. Karena tugas utamanya dalam hidup adalah untuk mendukung

    # Simple example presenting how persistent ID can be used to pickle
    # external objects by reference.
    
    import pickle
    import sqlite3
    from collections import namedtuple
    
    # Simple class representing a record in our database.
    MemoRecord = namedtuple("MemoRecord", "key, task")
    
    class DBPickler(pickle.Pickler):
    
        def persistent_id(self, obj):
            # Instead of pickling MemoRecord as a regular class instance, we emit a
            # persistent ID.
            if isinstance(obj, MemoRecord):
                # Here, our persistent ID is simply a tuple, containing a tag and a
                # key, which refers to a specific record in the database.
                return ("MemoRecord", obj.key)
            else:
                # If obj does not have a persistent ID, return None. This means obj
                # needs to be pickled as usual.
                return None
    
    
    class DBUnpickler(pickle.Unpickler):
    
        def __init__(self, file, connection):
            super().__init__(file)
            self.connection = connection
    
        def persistent_load(self, pid):
            # This method is invoked whenever a persistent ID is encountered.
            # Here, pid is the tuple returned by DBPickler.
            cursor = self.connection.cursor()
            type_tag, key_id = pid
            if type_tag == "MemoRecord":
                # Fetch the referenced record from the database and return it.
                cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
                key, task = cursor.fetchone()
                return MemoRecord(key, task)
            else:
                # Always raises an error if you cannot return the correct object.
                # Otherwise, the unpickler will think None is the object referenced
                # by the persistent ID.
                raise pickle.UnpicklingError("unsupported persistent object")
    
    
    def main():
        import io
        import pprint
    
        # Initialize and populate our database.
        conn = sqlite3.connect(":memory:")
        cursor = conn.cursor()
        cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
        tasks = (
            'give food to fish',
            'prepare group meeting',
            'fight with a zebra',
            )
        for task in tasks:
            cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))
    
        # Fetch the records to be pickled.
        cursor.execute("SELECT * FROM memos")
        memos = [MemoRecord(key, task) for key, task in cursor]
        # Save the records using our custom DBPickler.
        file = io.BytesIO()
        DBPickler(file).dump(memos)
    
        print("Pickled records:")
        pprint.pprint(memos)
    
        # Update a record, just for good measure.
        cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")
    
        # Load the records from the pickle data stream.
        file.seek(0)
        memos = DBUnpickler(file, conn).load()
    
        print("Unpickled records:")
        pprint.pprint(memos)
    
    
    if __name__ == '__main__':
        main()
    
    _6 file, pelaksana Python berhak untuk mengubah format serialisasi dengan cara yang tidak kompatibel mundur jika diperlukan. Format serialisasi dijamin kompatibel ke belakang di seluruh rilis Python asalkan protokol acar yang kompatibel dipilih dan kode pickling dan unpickling berurusan dengan perbedaan jenis Python 2 ke Python 3 jika data Anda melintasi batas bahasa perubahan yang unik itu

Perbandingan dengan # Simple example presenting how persistent ID can be used to pickle # external objects by reference. import pickle import sqlite3 from collections import namedtuple # Simple class representing a record in our database. MemoRecord = namedtuple("MemoRecord", "key, task") class DBPickler(pickle.Pickler): def persistent_id(self, obj): # Instead of pickling MemoRecord as a regular class instance, we emit a # persistent ID. if isinstance(obj, MemoRecord): # Here, our persistent ID is simply a tuple, containing a tag and a # key, which refers to a specific record in the database. return ("MemoRecord", obj.key) else: # If obj does not have a persistent ID, return None. This means obj # needs to be pickled as usual. return None class DBUnpickler(pickle.Unpickler): def __init__(self, file, connection): super().__init__(file) self.connection = connection def persistent_load(self, pid): # This method is invoked whenever a persistent ID is encountered. # Here, pid is the tuple returned by DBPickler. cursor = self.connection.cursor() type_tag, key_id = pid if type_tag == "MemoRecord": # Fetch the referenced record from the database and return it. cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),)) key, task = cursor.fetchone() return MemoRecord(key, task) else: # Always raises an error if you cannot return the correct object. # Otherwise, the unpickler will think None is the object referenced # by the persistent ID. raise pickle.UnpicklingError("unsupported persistent object") def main(): import io import pprint # Initialize and populate our database. conn = sqlite3.connect(":memory:") cursor = conn.cursor() cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)") tasks = ( 'give food to fish', 'prepare group meeting', 'fight with a zebra', ) for task in tasks: cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,)) # Fetch the records to be pickled. cursor.execute("SELECT * FROM memos") memos = [MemoRecord(key, task) for key, task in cursor] # Save the records using our custom DBPickler. file = io.BytesIO() DBPickler(file).dump(memos) print("Pickled records:") pprint.pprint(memos) # Update a record, just for good measure. cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1") # Load the records from the pickle data stream. file.seek(0) memos = DBUnpickler(file, conn).load() print("Unpickled records:") pprint.pprint(memos) if __name__ == '__main__': main() _1

Ada perbedaan mendasar antara protokol pickle dan JSON (JavaScript Object Notation)

  • JSON adalah format serialisasi teks (menghasilkan teks unicode, meskipun sebagian besar waktu kemudian dikodekan ke

    f = io.BytesIO()
    p = pickle.Pickler(f)
    p.dispatch_table = copyreg.dispatch_table.copy()
    p.dispatch_table[SomeClass] = reduce_SomeClass
    
    8), sedangkan pickle adalah format serialisasi biner;

  • JSON dapat dibaca manusia, sedangkan acar tidak;

  • JSON dapat dioperasikan dan banyak digunakan di luar ekosistem Python, sedangkan pickle khusus untuk Python;

  • JSON, secara default, hanya dapat mewakili subset dari tipe bawaan Python, dan tidak ada kelas khusus;

  • Tidak seperti pickle, deserializing JSON yang tidak dipercaya tidak dengan sendirinya menciptakan kerentanan eksekusi kode arbitrer

Lihat juga

Modul. modul pustaka standar yang memungkinkan serialisasi dan deserialisasi JSON

Format aliran data

Format data yang digunakan oleh khusus untuk Python. Ini memiliki keuntungan bahwa tidak ada batasan yang diberlakukan oleh standar eksternal seperti JSON atau XDR (yang tidak dapat mewakili berbagi pointer);

Secara default, format data menggunakan representasi biner yang relatif ringkas. Jika Anda membutuhkan karakteristik ukuran yang optimal, Anda dapat mengompres data acar secara efisien.

Modul berisi alat untuk menganalisis aliran data yang dihasilkan oleh. kode sumber memiliki komentar ekstensif tentang opcode yang digunakan oleh protokol acar

Saat ini ada 6 protokol berbeda yang dapat digunakan untuk pengawetan. Semakin tinggi protokol yang digunakan, semakin baru versi Python yang dibutuhkan untuk membaca acar yang dihasilkan

  • Protokol versi 0 adalah protokol asli "yang dapat dibaca manusia" dan kompatibel dengan versi sebelumnya dari Python

  • Protokol versi 1 adalah format biner lama yang juga kompatibel dengan versi Python sebelumnya

  • Protokol versi 2 diperkenalkan dengan Python 2. 3. Ini memberikan pengawetan yang jauh lebih efisien. Lihat PEP 307 untuk informasi tentang peningkatan yang dibawa oleh protokol 2

  • Protokol versi 3 ditambahkan di Python 3. 0. Ini memiliki dukungan eksplisit untuk objek dan tidak dapat dihapus oleh Python 2. x. Ini adalah protokol default di Python 3. 0–3. 7

  • Protokol versi 4 ditambahkan di Python 3. 4. Itu menambahkan dukungan untuk objek yang sangat besar, memilih lebih banyak jenis objek, dan beberapa pengoptimalan format data. Ini adalah protokol default yang dimulai dengan Python 3. 8. Lihat PEP 3154 untuk informasi tentang peningkatan yang dibawa oleh protokol 4

  • Protokol versi 5 ditambahkan di Python 3. 8. Itu menambahkan dukungan untuk data out-of-band dan speedup untuk data in-band. Lihat PEP 574 untuk informasi tentang peningkatan yang dibawa oleh protokol 5

Catatan

Serialisasi adalah gagasan yang lebih primitif daripada kegigihan; . Modul dapat mengubah objek kompleks menjadi aliran byte dan dapat mengubah aliran byte menjadi objek dengan struktur internal yang sama. Mungkin hal yang paling jelas untuk dilakukan dengan aliran byte ini adalah menuliskannya ke file, tetapi juga memungkinkan untuk mengirimnya melalui jaringan atau menyimpannya dalam database. Modul ini menyediakan antarmuka sederhana untuk memilih dan memisahkan objek pada file database bergaya DBM

Antarmuka Modul

Untuk membuat serial hierarki objek, Anda cukup memanggil fungsi. Demikian pula, untuk membatalkan serial aliran data, Anda memanggil fungsi tersebut. Namun, jika Anda ingin lebih mengontrol serialisasi dan de-serialisasi, Anda dapat membuat objek masing-masing

Modul ini menyediakan konstanta berikut

acar. HIGHEST_PROTOCOL

Bilangan bulat, tertinggi yang tersedia. Nilai ini dapat diteruskan sebagai nilai protokol ke fungsi dan juga konstruktor

acar. DEFAULT_PROTOCOL

Bilangan bulat, standar yang digunakan untuk pengawetan. Mungkin kurang dari. Saat ini protokol defaultnya adalah 4, pertama kali diperkenalkan di Python 3. 4 dan tidak kompatibel dengan versi sebelumnya

Berubah di versi 3. 0. Protokol defaultnya adalah 3.

Berubah di versi 3. 8. Protokol standarnya adalah 4.

Modul ini menyediakan fungsi-fungsi berikut untuk mempermudah proses pengawetan

acar. dump(obj , berkas, protocol=None, *, fix_imports=True, buffer_callback=None)

Tulis representasi acar dari objek obj ke file yang terbuka. Ini setara dengan

copyreg.pickle(SomeClass, reduce_SomeClass)
f = io.BytesIO()
p = pickle.Pickler(f)
_9

File argumen, protokol, fix_imports dan buffer_callback memiliki arti yang sama seperti pada konstruktor

Berubah di versi 3. 8. Argumen buffer_callback telah ditambahkan.

acar. dumps(obj , protokol=None, *, fix_imports=True, buffer_callback=None)

Kembalikan representasi acar dari objek obj sebagai objek, alih-alih menulisnya ke file

Protokol argumen, fix_imports dan buffer_callback memiliki arti yang sama seperti pada konstruktor

Berubah di versi 3. 8. Argumen buffer_callback telah ditambahkan.

acar. muat(file , *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

Baca representasi acar dari suatu objek dari file yang terbuka dan kembalikan hierarki objek yang dibentuk kembali yang ditentukan di dalamnya. Ini setara dengan

class TextReader:
    """Print and number lines in a text file."""

    def __init__(self, filename):
        self.filename = filename
        self.file = open(filename)
        self.lineno = 0

    def readline(self):
        self.lineno += 1
        line = self.file.readline()
        if not line:
            return None
        if line.endswith('\n'):
            line = line[:-1]
        return "%i: %s" % (self.lineno, line)

    def __getstate__(self):
        # Copy the object's state from self.__dict__ which contains
        # all our instance attributes. Always use the dict.copy()
        # method to avoid modifying the original state.
        state = self.__dict__.copy()
        # Remove the unpicklable entries.
        del state['file']
        return state

    def __setstate__(self, state):
        # Restore instance attributes (i.e., filename and lineno).
        self.__dict__.update(state)
        # Restore the previously opened file's state. To do so, we need to
        # reopen it and read from it until the line count is restored.
        file = open(self.filename)
        for _ in range(self.lineno):
            file.readline()
        # Finally, save the file.
        self.file = file
_3

Versi protokol acar terdeteksi secara otomatis, jadi tidak diperlukan argumen protokol. Byte yang melewati representasi acar dari objek akan diabaikan

File argumen, fix_imports, encoding, error, strict dan buffer memiliki arti yang sama seperti pada konstruktor

Berubah di versi 3. 8. Argumen penyangga telah ditambahkan.

acar. memuat(data , /, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

Kembalikan hierarki objek yang dibentuk kembali dari data representasi acar dari suatu objek. data harus a

Versi protokol acar terdeteksi secara otomatis, jadi tidak diperlukan argumen protokol. Byte yang melewati representasi acar dari objek akan diabaikan

Argumen fix_imports, encoding, error, strict dan buffer memiliki arti yang sama seperti pada konstruktor

Berubah di versi 3. 8. Argumen penyangga telah ditambahkan.

Modul ini mendefinisikan tiga pengecualian

pengecualian acar. PickleError

Kelas dasar umum untuk pengecualian pengawetan lainnya. Itu mewarisi

pengecualian acar. PicklingError

Kesalahan muncul saat objek yang tidak dapat diambil ditemukan oleh. Itu mewarisi

Lihat untuk mempelajari jenis benda apa yang bisa diasinkan

pengecualian acar. UnpicklingError

Kesalahan muncul saat ada masalah saat membongkar objek, seperti kerusakan data atau pelanggaran keamanan. Itu mewarisi

Perhatikan bahwa pengecualian lain juga dapat dimunculkan selama unpickling, termasuk (namun tidak terbatas pada) AttributeError, EOFError, ImportError, dan IndexError

Modul mengekspor tiga kelas, , dan

kelas acar. Pickler(file , protokol=None, *, fix_imports=True, buffer_callback=None)

Ini membutuhkan file biner untuk menulis aliran data acar

Argumen protokol opsional, bilangan bulat, memberi tahu pickler untuk menggunakan protokol yang diberikan; . Jika tidak ditentukan, defaultnya adalah. Jika angka negatif ditentukan, dipilih

Argumen file harus memiliki metode write() yang menerima argumen byte tunggal. Dengan demikian dapat berupa file on-disk yang dibuka untuk penulisan biner, instance, atau objek khusus lainnya yang memenuhi antarmuka ini

Jika fix_imports benar dan protokol kurang dari 3, acar akan mencoba memetakan nama Python 3 baru ke nama modul lama yang digunakan dalam Python 2, sehingga aliran data acar dapat dibaca dengan Python 2

Jika buffer_callback adalah Tidak Ada (default), tampilan buffer diserialkan ke dalam file sebagai bagian dari aliran acar

Jika buffer_callback bukan Tidak ada, maka dapat dipanggil beberapa kali dengan tampilan buffer. Jika callback mengembalikan nilai false (seperti Tidak ada), buffer yang diberikan adalah ; . e. di dalam aliran acar

Ini adalah kesalahan jika buffer_callback bukan Tidak Ada dan protokol Tidak ada atau lebih kecil dari 5

Berubah di versi 3. 8. Argumen buffer_callback telah ditambahkan.

dump(obj)

Tulis representasi acar dari objek ke objek file terbuka yang diberikan dalam konstruktor

persistent_id(obj)

Tidak melakukan apa pun secara default. Ini ada sehingga subkelas dapat menimpanya

Jika mengembalikan

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
_0, obj diasamkan seperti biasa. Nilai lain apa pun menyebabkan memancarkan nilai yang dikembalikan sebagai ID persisten untuk objek. Arti dari ID persisten ini harus ditentukan oleh. Perhatikan bahwa nilai yang dikembalikan oleh itu sendiri tidak dapat memiliki ID persisten

Lihat detail dan contoh penggunaan

dispatch_table

Tabel pengiriman objek pickler adalah daftar fungsi reduksi dari jenis yang dapat dideklarasikan menggunakan. Ini adalah pemetaan yang kuncinya adalah kelas dan nilainya adalah fungsi reduksi. Fungsi reduksi mengambil satu argumen dari kelas terkait dan harus sesuai dengan antarmuka yang sama dengan metode

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
5

Secara default, objek pickler tidak akan memiliki atribut, dan akan menggunakan tabel pengiriman global yang dikelola oleh modul. Namun, untuk menyesuaikan pengawetan untuk objek pickler tertentu, seseorang dapat mengatur atributnya ke objek seperti dict. Alternatifnya, jika subkelas dari memiliki atribut maka ini akan digunakan sebagai tabel pengiriman default untuk instance dari kelas tersebut

Lihat untuk contoh penggunaan

Baru di versi 3. 3

reducer_override(obj)

Reducer khusus yang dapat didefinisikan dalam subclass. Metode ini diprioritaskan daripada peredam apa pun di. Itu harus sesuai dengan antarmuka yang sama dengan metode

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
5, dan secara opsional dapat mengembalikan
class ZeroCopyByteArray(bytearray):

    def __reduce_ex__(self, protocol):
        if protocol >= 5:
            return type(self)._reconstruct, (PickleBuffer(self),), None
        else:
            # PickleBuffer is forbidden with pickle protocols <= 4.
            return type(self)._reconstruct, (bytearray(self),)

    @classmethod
    def _reconstruct(cls, obj):
        with memoryview(obj) as m:
            # Get a handle over the original buffer object
            obj = m.obj
            if type(obj) is cls:
                # Original buffer object is a ZeroCopyByteArray, return it
                # as-is.
                return obj
            else:
                return cls(obj)
4 untuk mundur pada reduksi terdaftar - ke acar
class ZeroCopyByteArray(bytearray):

    def __reduce_ex__(self, protocol):
        if protocol >= 5:
            return type(self)._reconstruct, (PickleBuffer(self),), None
        else:
            # PickleBuffer is forbidden with pickle protocols <= 4.
            return type(self)._reconstruct, (bytearray(self),)

    @classmethod
    def _reconstruct(cls, obj):
        with memoryview(obj) as m:
            # Get a handle over the original buffer object
            obj = m.obj
            if type(obj) is cls:
                # Original buffer object is a ZeroCopyByteArray, return it
                # as-is.
                return obj
            else:
                return cls(obj)
6

Untuk contoh terperinci, lihat

Baru di versi 3. 8

cepat

Tidak digunakan lagi. Aktifkan mode cepat jika disetel ke nilai sebenarnya. Mode cepat menonaktifkan penggunaan memo, sehingga mempercepat proses pengawetan dengan tidak menghasilkan opcode PUT yang berlebihan. Itu tidak boleh digunakan dengan objek referensi diri, melakukan sebaliknya akan menyebabkan berulang tanpa batas

Gunakan jika Anda membutuhkan acar yang lebih padat

kelas acar. Unpickler(file , *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

Ini membutuhkan file biner untuk membaca aliran data acar

Versi protokol acar terdeteksi secara otomatis, jadi tidak diperlukan argumen protokol

File argumen harus memiliki tiga metode, metode read() yang mengambil argumen bilangan bulat, metode readinto() yang mengambil argumen buffer, dan metode readline() yang tidak memerlukan argumen, seperti pada antarmuka. Dengan demikian file dapat berupa file on-disk yang dibuka untuk pembacaan biner, objek, atau objek khusus lainnya yang memenuhi antarmuka ini

Argumen opsional fix_imports, encoding dan error digunakan untuk mengontrol dukungan kompatibilitas untuk aliran acar yang dihasilkan oleh Python 2. Jika fix_imports benar, acar akan mencoba memetakan nama Python 2 lama ke nama baru yang digunakan di Python 3. Pengodean dan kesalahan memberi tahu pickle cara mendekode instance string 8-bit yang diasinkan oleh Python 2; . Pengkodean dapat berupa 'byte' untuk membaca instance string 8-bit ini sebagai objek byte. Menggunakan

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_01 diperlukan untuk menghapus array NumPy dan instance dari , dan diasamkan oleh Python 2

Jika buffer adalah Tidak Ada (default), maka semua data yang diperlukan untuk deserialisasi harus dimuat dalam aliran acar. Ini berarti bahwa argumen buffer_callback adalah Tidak ada saat a dipakai (atau saat atau dipanggil)

Jika buffer bukan Tidak ada, itu harus merupakan iterable dari objek berkemampuan buffer yang dikonsumsi setiap kali aliran acar mereferensikan tampilan buffer. Buffer tersebut telah diberikan untuk buffer_callback dari objek Pickler

Berubah di versi 3. 8. Argumen penyangga telah ditambahkan.

memuat()

Baca representasi acar dari suatu objek dari objek file terbuka yang diberikan dalam konstruktor, dan kembalikan hierarki objek yang dibentuk kembali yang ditentukan di dalamnya. Byte yang melewati representasi acar dari objek akan diabaikan

persistent_load(pid)

Naikkan secara default

Jika ditentukan, harus mengembalikan objek yang ditentukan oleh pid ID persisten. Jika ditemukan ID persisten yang tidak valid, an harus dinaikkan

Lihat detail dan contoh penggunaan

find_class(modul , nama)

Impor modul jika perlu dan kembalikan objek yang disebut nama darinya, di mana argumen modul dan nama adalah objek. Perhatikan, tidak seperti namanya, ini juga digunakan untuk menemukan fungsi

Subclass dapat mengesampingkan ini untuk mendapatkan kontrol atas jenis objek apa dan bagaimana mereka dapat dimuat, berpotensi mengurangi risiko keamanan. Lihat untuk detailnya

Memunculkan

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
13 dengan argumen
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
14,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
15

kelas acar. PickleBuffer(penyangga)

Pembungkus untuk buffer yang mewakili data picklable. buffer harus berupa objek, seperti array berdimensi atau N

sendiri merupakan penyedia buffer, oleh karena itu dimungkinkan untuk meneruskannya ke API lain yang mengharapkan objek penyedia buffer, seperti

objek hanya dapat diserialisasi menggunakan protokol acar 5 atau lebih tinggi. Mereka memenuhi syarat untuk

Baru di versi 3. 8

mentah()

Kembalikan a dari area memori yang mendasari buffer ini. Objek yang dikembalikan adalah tampilan memori C-contiguous satu dimensi dengan format

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
20 (unsigned byte). dinaikkan jika buffer tidak bersebelahan dengan C- atau Fortran

rilis()

Lepaskan buffer dasar yang diekspos oleh objek PickleBuffer

Apa yang bisa diasinkan dan tidak diasamkan?

Jenis-jenis berikut dapat diasinkan

  • import io
    import pickle
    
    class MyClass:
        my_attribute = 1
    
    class MyPickler(pickle.Pickler):
        def reducer_override(self, obj):
            """Custom reducer for MyClass."""
            if getattr(obj, "__name__", None) == "MyClass":
                return type, (obj.__name__, obj.__bases__,
                              {'my_attribute': obj.my_attribute})
            else:
                # For any other object, fallback to usual reduction
                return NotImplemented
    
    f = io.BytesIO()
    p = MyPickler(f)
    p.dump(MyClass)
    
    del MyClass
    
    unpickled_class = pickle.loads(f.getvalue())
    
    assert isinstance(unpickled_class, type)
    assert unpickled_class.__name__ == "MyClass"
    assert unpickled_class.my_attribute == 1
    
    0,
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    23, dan
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    24;

  • bilangan bulat, bilangan floating-point, bilangan kompleks;

  • string, byte, bytearray;

  • tupel, daftar, set, dan kamus yang hanya berisi objek yang dapat dipilih;

  • fungsi (bawaan dan ditentukan pengguna) dapat diakses dari tingkat atas modul (menggunakan , bukan );

  • kelas dapat diakses dari tingkat atas modul;

  • contoh dari kelas-kelas tersebut yang hasil pemanggilannya

    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    27 dapat dipilih (lihat bagian untuk detailnya)

Upaya untuk mengasinkan objek yang tidak dapat diawetkan akan menimbulkan pengecualian; . Mencoba memilih struktur data yang sangat rekursif dapat melebihi kedalaman rekursi maksimum, a akan dimunculkan dalam kasus ini. Anda dapat dengan hati-hati menaikkan batas ini dengan

Perhatikan bahwa fungsi (bawaan dan ditentukan pengguna) diasamkan oleh fully , bukan berdasarkan nilai. Ini berarti bahwa hanya nama fungsi yang diasamkan, bersama dengan nama modul dan kelas yang memuatnya. Baik kode fungsi, maupun atribut fungsinya tidak diasamkan. Jadi modul pendefinisian harus dapat diimpor di lingkungan unpickling, dan modul harus berisi objek bernama, jika tidak, pengecualian akan dimunculkan.

Demikian pula, kelas diasamkan dengan nama yang memenuhi syarat, jadi batasan yang sama di lingkungan unpickling berlaku. Perhatikan bahwa tidak ada kode atau data kelas yang diasamkan, jadi dalam contoh berikut atribut kelas

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
31 tidak dipulihkan di lingkungan unpickling

class Foo:
    attr = 'A class attribute'

picklestring = pickle.dumps(Foo)

Pembatasan ini adalah mengapa fungsi dan kelas picklable harus didefinisikan di tingkat atas modul

Demikian pula, ketika instance kelas diasamkan, kode dan data kelasnya tidak diasamkan bersama mereka. Hanya data instance yang diasamkan. Ini dilakukan dengan sengaja, sehingga Anda dapat memperbaiki bug di kelas atau menambahkan metode ke kelas dan tetap memuat objek yang dibuat dengan versi kelas sebelumnya. Jika Anda berencana untuk memiliki objek berumur panjang yang akan melihat banyak versi kelas, mungkin bermanfaat untuk memasukkan nomor versi ke dalam objek sehingga konversi yang sesuai dapat dilakukan dengan metode

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
32 kelas

Contoh Kelas Pengawetan

Di bagian ini, kami menjelaskan mekanisme umum yang tersedia bagi Anda untuk mendefinisikan, menyesuaikan, dan mengontrol bagaimana instance kelas dipilih dan dipisahkan

Dalam kebanyakan kasus, tidak diperlukan kode tambahan untuk membuat instance dapat dipilih. Secara default, pickle akan mengambil kelas dan atribut dari sebuah instance melalui introspeksi. Ketika instance kelas tidak dipilih, metode

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
33 biasanya tidak dipanggil. Perilaku default pertama-tama membuat instance yang tidak diinisialisasi dan kemudian memulihkan atribut yang disimpan. Kode berikut menunjukkan penerapan perilaku ini

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj

Kelas dapat mengubah perilaku default dengan menyediakan satu atau beberapa metode khusus

objek. __getnewargs_ex__()

Dalam protokol 2 dan yang lebih baru, kelas yang mengimplementasikan metode dapat mendikte nilai yang diteruskan ke metode setelah unpickling. Metode harus mengembalikan pasangan

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
36 di mana args adalah tupel argumen posisional dan kwargs kamus argumen bernama untuk membangun objek. Itu akan diteruskan ke metode setelah dicabut

Anda harus menerapkan metode ini jika metode kelas Anda memerlukan argumen kata kunci saja. Jika tidak, disarankan agar kompatibilitas diterapkan

Berubah di versi 3. 6. sekarang digunakan dalam protokol 2 dan 3.

objek. __getnewargs__()

Metode ini memiliki tujuan yang sama seperti , tetapi hanya mendukung argumen posisional. Itu harus mengembalikan Tuple argumen

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
42 yang akan diteruskan ke metode setelah unpickling

tidak akan dipanggil jika didefinisikan

Berubah di versi 3. 6. Sebelum Python 3. 6, dipanggil bukan di protokol 2 dan 3.

objek. __getstate__()

Kelas selanjutnya dapat memengaruhi bagaimana instance mereka diasamkan dengan mengganti metode. Itu dipanggil dan objek yang dikembalikan diasamkan sebagai konten untuk instance, alih-alih status default. Ada beberapa kasus

  • Untuk kelas yang tidak memiliki instance dan no , status defaultnya adalah

    import io
    import pickle
    
    class MyClass:
        my_attribute = 1
    
    class MyPickler(pickle.Pickler):
        def reducer_override(self, obj):
            """Custom reducer for MyClass."""
            if getattr(obj, "__name__", None) == "MyClass":
                return type, (obj.__name__, obj.__bases__,
                              {'my_attribute': obj.my_attribute})
            else:
                # For any other object, fallback to usual reduction
                return NotImplemented
    
    f = io.BytesIO()
    p = MyPickler(f)
    p.dump(MyClass)
    
    del MyClass
    
    unpickled_class = pickle.loads(f.getvalue())
    
    assert isinstance(unpickled_class, type)
    assert unpickled_class.__name__ == "MyClass"
    assert unpickled_class.my_attribute == 1
    
    0

  • Untuk kelas yang memiliki instance dan no , status defaultnya adalah

    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    54

  • Untuk kelas yang memiliki instance dan , status defaultnya adalah tuple yang terdiri dari dua kamus.

    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    _54, dan nama slot pemetaan kamus ke nilai slot. Hanya slot yang memiliki nilai yang termasuk dalam yang terakhir

  • Untuk kelas yang memiliki dan tidak memiliki instance, status defaultnya adalah tuple yang item pertamanya adalah

    import io
    import pickle
    
    class MyClass:
        my_attribute = 1
    
    class MyPickler(pickle.Pickler):
        def reducer_override(self, obj):
            """Custom reducer for MyClass."""
            if getattr(obj, "__name__", None) == "MyClass":
                return type, (obj.__name__, obj.__bases__,
                              {'my_attribute': obj.my_attribute})
            else:
                # For any other object, fallback to usual reduction
                return NotImplemented
    
    f = io.BytesIO()
    p = MyPickler(f)
    p.dump(MyClass)
    
    del MyClass
    
    unpickled_class = pickle.loads(f.getvalue())
    
    assert isinstance(unpickled_class, type)
    assert unpickled_class.__name__ == "MyClass"
    assert unpickled_class.my_attribute == 1
    
    0 dan item keduanya adalah nama slot pemetaan kamus ke nilai slot yang dijelaskan di poin sebelumnya

Berubah di versi 3. 11. Menambahkan implementasi default dari metode

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
27 di kelas.

objek. __setstatus__(status)

Saat unpickling, jika class mendefinisikan , itu disebut dengan unpickled state. Dalam hal ini, tidak ada persyaratan untuk objek status menjadi kamus. Jika tidak, status acar harus berupa kamus dan itemnya ditetapkan ke kamus instance baru

Catatan

Jika mengembalikan nilai yang salah, metode tidak akan dipanggil saat unpickling

Lihat bagian untuk informasi selengkapnya tentang cara menggunakan metode

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
27 dan
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
32

Catatan

Pada waktu unpickling, beberapa metode seperti

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
68,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
69, atau
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
70 dapat dipanggil pada instance. Jika metode tersebut bergantung pada beberapa invarian internal yang benar, tipe tersebut harus mengimplementasikan
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
35 untuk membuat invarian seperti itu, karena
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
33 tidak dipanggil saat membongkar instance

Seperti yang akan kita lihat, acar tidak langsung menggunakan metode yang dijelaskan di atas. Faktanya, metode ini adalah bagian dari protokol penyalinan yang mengimplementasikan metode khusus

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
5. Protokol salin menyediakan antarmuka terpadu untuk mengambil data yang diperlukan untuk pengawetan dan penyalinan objek.

Meskipun kuat, menerapkan

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
_5 langsung di kelas Anda rawan kesalahan. Untuk alasan ini, desainer kelas harus menggunakan antarmuka tingkat tinggi (mis. e. ,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_34,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
27 dan
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
32) jika memungkinkan. Kami akan menunjukkan, bagaimanapun, kasus di mana menggunakan
import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
5 adalah satu-satunya pilihan atau mengarah ke pengawetan yang lebih efisien atau keduanya

objek. __reduce__()

Antarmuka saat ini didefinisikan sebagai berikut. Metode ini tidak memerlukan argumen dan akan mengembalikan string atau sebaiknya tupel (objek yang dikembalikan sering disebut sebagai "nilai kurangi")

Jika sebuah string dikembalikan, string tersebut harus ditafsirkan sebagai nama variabel global. Itu harus menjadi nama lokal objek relatif terhadap modulnya; . Perilaku ini biasanya berguna untuk lajang

Ketika sebuah tuple dikembalikan, panjangnya harus antara dua dan enam item. Item opsional dapat dihilangkan, atau

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
0 dapat diberikan sebagai nilainya. Semantik dari setiap item sudah beres

  • Objek callable yang akan dipanggil untuk membuat versi awal objek

  • Tuple argumen untuk objek yang bisa dipanggil. Tuple kosong harus diberikan jika callable tidak menerima argumen apa pun

  • Secara opsional, status objek, yang akan diteruskan ke metode objek seperti yang dijelaskan sebelumnya. Jika objek tidak memiliki metode seperti itu, nilainya harus berupa kamus dan akan ditambahkan ke atribut objek

  • Opsional, iterator (dan bukan urutan) menghasilkan item yang berurutan. Barang-barang ini akan ditambahkan ke objek menggunakan

    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    83 atau, secara berkelompok, menggunakan
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    84. Ini terutama digunakan untuk daftar subkelas, tetapi dapat digunakan oleh kelas lain selama mereka memiliki metode
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    85 dan
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    86 dengan tanda tangan yang sesuai. (Apakah
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    85 atau
    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    86 digunakan tergantung pada versi protokol acar mana yang digunakan serta jumlah item yang ditambahkan, jadi keduanya harus didukung. )

  • Secara opsional, iterator (bukan urutan) menghasilkan pasangan nilai kunci yang berurutan. Barang-barang ini akan disimpan ke objek menggunakan ________0______89. Ini terutama digunakan untuk subclass kamus, tetapi dapat digunakan oleh kelas lain selama mereka menerapkannya

  • Secara opsional, callable dengan tanda tangan ________0______91. Callable ini memungkinkan pengguna untuk secara terprogram mengontrol perilaku pembaruan status dari objek tertentu, alih-alih menggunakan metode statis

    class ZeroCopyByteArray(bytearray):
    
        def __reduce_ex__(self, protocol):
            if protocol >= 5:
                return type(self)._reconstruct, (PickleBuffer(self),), None
            else:
                # PickleBuffer is forbidden with pickle protocols <= 4.
                return type(self)._reconstruct, (bytearray(self),)
    
        @classmethod
        def _reconstruct(cls, obj):
            with memoryview(obj) as m:
                # Get a handle over the original buffer object
                obj = m.obj
                if type(obj) is cls:
                    # Original buffer object is a ZeroCopyByteArray, return it
                    # as-is.
                    return obj
                else:
                    return cls(obj)
    
    6. Jika bukan
    import io
    import pickle
    
    class MyClass:
        my_attribute = 1
    
    class MyPickler(pickle.Pickler):
        def reducer_override(self, obj):
            """Custom reducer for MyClass."""
            if getattr(obj, "__name__", None) == "MyClass":
                return type, (obj.__name__, obj.__bases__,
                              {'my_attribute': obj.my_attribute})
            else:
                # For any other object, fallback to usual reduction
                return NotImplemented
    
    f = io.BytesIO()
    p = MyPickler(f)
    p.dump(MyClass)
    
    del MyClass
    
    unpickled_class = pickle.loads(f.getvalue())
    
    assert isinstance(unpickled_class, type)
    assert unpickled_class.__name__ == "MyClass"
    assert unpickled_class.my_attribute == 1
    
    _0, panggilan ini akan diprioritaskan daripada
    class ZeroCopyByteArray(bytearray):
    
        def __reduce_ex__(self, protocol):
            if protocol >= 5:
                return type(self)._reconstruct, (PickleBuffer(self),), None
            else:
                # PickleBuffer is forbidden with pickle protocols <= 4.
                return type(self)._reconstruct, (bytearray(self),)
    
        @classmethod
        def _reconstruct(cls, obj):
            with memoryview(obj) as m:
                # Get a handle over the original buffer object
                obj = m.obj
                if type(obj) is cls:
                    # Original buffer object is a ZeroCopyByteArray, return it
                    # as-is.
                    return obj
                else:
                    return cls(obj)
    
    6

    Baru di versi 3. 8. Item tupel keenam opsional,

    def save(obj):
        return (obj.__class__, obj.__dict__)
    
    def restore(cls, attributes):
        obj = cls.__new__(cls)
        obj.__dict__.update(attributes)
        return obj
    
    91, telah ditambahkan.

objek. __reduce_ex__(protokol)

Atau, metode dapat didefinisikan. Satu-satunya perbedaan adalah metode ini harus menggunakan argumen bilangan bulat tunggal, versi protokol. Saat ditentukan, acar akan lebih memilihnya daripada metode. Selain itu, secara otomatis menjadi sinonim untuk versi yang diperluas. Penggunaan utama untuk metode ini adalah untuk memberikan nilai pengurangan yang kompatibel dengan mundur untuk rilis Python yang lebih lama

Kegigihan Objek Eksternal

Untuk kepentingan kegigihan objek, modul mendukung gagasan referensi ke objek di luar aliran data acar. Objek tersebut direferensikan oleh ID persisten, yang harus berupa string karakter alfanumerik (untuk protokol 0) atau hanya objek arbitrer (untuk protokol yang lebih baru)

Resolusi ID persisten tersebut tidak ditentukan oleh modul;

Untuk memilih objek yang memiliki ID persisten eksternal, pickler harus memiliki metode khusus yang menggunakan objek sebagai argumen dan mengembalikan

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
0 atau ID persisten untuk objek tersebut. Ketika
import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
_0 dikembalikan, pickler hanya mengasinkan objek seperti biasa. Saat string ID persisten dikembalikan, pickler akan mengambil objek tersebut, bersama dengan penanda sehingga unpickler akan mengenalinya sebagai ID persisten

Untuk menghapus objek eksternal, unpickler harus memiliki metode khusus yang menggunakan objek ID persisten dan mengembalikan objek yang direferensikan

Berikut adalah contoh komprehensif yang menyajikan bagaimana ID persisten dapat digunakan untuk mengambil objek eksternal dengan referensi

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_

Tabel Pengiriman

Jika seseorang ingin menyesuaikan pengawetan beberapa kelas tanpa mengganggu kode lain yang bergantung pada pengawetan, maka seseorang dapat membuat pengawetan dengan tabel pengiriman pribadi

Tabel pengiriman global yang dikelola oleh modul tersedia sebagai

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
10. Oleh karena itu, seseorang dapat memilih untuk menggunakan salinan
# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
10 yang dimodifikasi sebagai tabel pengiriman pribadi

Misalnya

f = io.BytesIO()
p = pickle.Pickler(f)
p.dispatch_table = copyreg.dispatch_table.copy()
p.dispatch_table[SomeClass] = reduce_SomeClass

membuat instance dari dengan tabel pengiriman pribadi yang menangani kelas

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
13 secara khusus. Atau, kode

class MyPickler(pickle.Pickler):
    dispatch_table = copyreg.dispatch_table.copy()
    dispatch_table[SomeClass] = reduce_SomeClass
f = io.BytesIO()
p = MyPickler(f)

melakukan hal yang sama tetapi semua contoh

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_14 secara default akan berbagi tabel pengiriman pribadi. Di sisi lain, kode

copyreg.pickle(SomeClass, reduce_SomeClass)
f = io.BytesIO()
p = pickle.Pickler(f)
_

memodifikasi tabel pengiriman global yang dibagikan oleh semua pengguna modul

Menangani Objek Stateful

Berikut adalah contoh yang menunjukkan cara memodifikasi perilaku pengawetan untuk suatu kelas. Kelas

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
16 membuka file teks, dan mengembalikan nomor baris dan konten baris setiap kali metode
# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
17 dipanggil. Jika instance
# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_16 diasamkan, semua atribut kecuali anggota objek file disimpan. Saat instance dilepas, file dibuka kembali, dan pembacaan dilanjutkan dari lokasi terakhir. Metode
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
32 dan
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
27 digunakan untuk menerapkan perilaku ini

class TextReader:
    """Print and number lines in a text file."""

    def __init__(self, filename):
        self.filename = filename
        self.file = open(filename)
        self.lineno = 0

    def readline(self):
        self.lineno += 1
        line = self.file.readline()
        if not line:
            return None
        if line.endswith('\n'):
            line = line[:-1]
        return "%i: %s" % (self.lineno, line)

    def __getstate__(self):
        # Copy the object's state from self.__dict__ which contains
        # all our instance attributes. Always use the dict.copy()
        # method to avoid modifying the original state.
        state = self.__dict__.copy()
        # Remove the unpicklable entries.
        del state['file']
        return state

    def __setstate__(self, state):
        # Restore instance attributes (i.e., filename and lineno).
        self.__dict__.update(state)
        # Restore the previously opened file's state. To do so, we need to
        # reopen it and read from it until the line count is restored.
        file = open(self.filename)
        for _ in range(self.lineno):
            file.readline()
        # Finally, save the file.
        self.file = file

Contoh penggunaan mungkin seperti ini

>>> reader = TextReader("hello.txt")
>>> reader.readline()
'1: Hello world!'
>>> reader.readline()
'2: I am line number two.'
>>> new_reader = pickle.loads(pickle.dumps(reader))
>>> new_reader.readline()
'3: Goodbye!'

Pengurangan Kustom untuk Jenis, Fungsi, dan Objek Lainnya

Baru di versi 3. 8

Terkadang, mungkin tidak cukup fleksibel. Secara khusus kita mungkin ingin menyesuaikan pengawetan berdasarkan kriteria lain selain jenis objek, atau kita mungkin ingin menyesuaikan pengawetan fungsi dan kelas

Untuk kasus tersebut, dimungkinkan untuk membuat subkelas dari kelas tersebut dan mengimplementasikan sebuah metode. Metode ini dapat mengembalikan tuple pengurangan sewenang-wenang (lihat

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
5). Alternatifnya dapat mengembalikan
class ZeroCopyByteArray(bytearray):

    def __reduce_ex__(self, protocol):
        if protocol >= 5:
            return type(self)._reconstruct, (PickleBuffer(self),), None
        else:
            # PickleBuffer is forbidden with pickle protocols <= 4.
            return type(self)._reconstruct, (bytearray(self),)

    @classmethod
    def _reconstruct(cls, obj):
        with memoryview(obj) as m:
            # Get a handle over the original buffer object
            obj = m.obj
            if type(obj) is cls:
                # Original buffer object is a ZeroCopyByteArray, return it
                # as-is.
                return obj
            else:
                return cls(obj)
_4 ke fallback ke perilaku tradisional

Jika kedua dan didefinisikan, maka metode diprioritaskan

Catatan

Untuk alasan performa, mungkin tidak dipanggil untuk objek berikut.

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
0,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
23,
def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
24, dan contoh persis dari , , , , , , , , dan

Berikut adalah contoh sederhana di mana kami mengizinkan pengawetan dan merekonstruksi kelas tertentu

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        """Custom reducer for MyClass."""
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__,
                          {'my_attribute': obj.my_attribute})
        else:
            # For any other object, fallback to usual reduction
            return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

del MyClass

unpickled_class = pickle.loads(f.getvalue())

assert isinstance(unpickled_class, type)
assert unpickled_class.__name__ == "MyClass"
assert unpickled_class.my_attribute == 1
_

Buffer Out-of-band

Baru di versi 3. 8

Dalam beberapa konteks, modul digunakan untuk mentransfer data dalam jumlah besar. Oleh karena itu, penting untuk meminimalkan jumlah salinan memori, untuk mempertahankan kinerja dan konsumsi sumber daya. Namun, operasi normal modul, karena mengubah struktur objek seperti grafik menjadi aliran byte berurutan, secara intrinsik melibatkan penyalinan data ke dan dari aliran acar.

Batasan ini dapat dihindari jika penyedia (implementasi tipe objek yang akan ditransfer) dan konsumen (implementasi sistem komunikasi) mendukung fasilitas transfer out-of-band yang disediakan oleh protokol pickle 5 dan lebih tinggi

API penyedia

Objek data besar yang akan diambil harus menerapkan metode

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
98 khusus untuk protokol 5 dan lebih tinggi, yang mengembalikan sebuah instance (bukannya e. g. objek) untuk data besar apa pun

Objek memberi sinyal bahwa buffer yang mendasarinya memenuhi syarat untuk transfer data out-of-band. Objek tersebut tetap kompatibel dengan penggunaan modul secara normal. Namun, konsumen juga dapat ikut serta untuk mengatakan bahwa mereka akan menangani buffer tersebut sendiri

API Konsumen

Sebuah sistem komunikasi dapat mengaktifkan penanganan khusus dari objek yang dihasilkan saat membuat serial grafik objek

Di sisi pengirim, ia perlu meneruskan argumen buffer_callback ke (atau ke fungsi or ), yang akan dipanggil dengan masing-masing dihasilkan saat mengawetkan grafik objek. Buffer yang diakumulasikan oleh buffer_callback tidak akan melihat datanya disalin ke aliran acar, hanya penanda murah yang akan dimasukkan

Di sisi penerima, perlu meneruskan argumen buffer ke (atau ke fungsi or ), yang merupakan iterable dari buffer yang diteruskan ke buffer_callback. Iterable itu harus menghasilkan buffer dalam urutan yang sama seperti yang diteruskan ke buffer_callback. Buffer tersebut akan memberikan data yang diharapkan oleh rekonstruktor objek yang pengawetannya menghasilkan objek asli

Antara sisi pengirim dan sisi penerima, sistem komunikasi bebas menerapkan mekanisme transfernya sendiri untuk buffer out-of-band. Pengoptimalan potensial mencakup penggunaan memori bersama atau kompresi yang bergantung pada tipe data

Contoh

Berikut adalah contoh sepele di mana kami mengimplementasikan subkelas yang dapat berpartisipasi dalam pengawetan buffer out-of-band

class ZeroCopyByteArray(bytearray):

    def __reduce_ex__(self, protocol):
        if protocol >= 5:
            return type(self)._reconstruct, (PickleBuffer(self),), None
        else:
            # PickleBuffer is forbidden with pickle protocols <= 4.
            return type(self)._reconstruct, (bytearray(self),)

    @classmethod
    def _reconstruct(cls, obj):
        with memoryview(obj) as m:
            # Get a handle over the original buffer object
            obj = m.obj
            if type(obj) is cls:
                # Original buffer object is a ZeroCopyByteArray, return it
                # as-is.
                return obj
            else:
                return cls(obj)

Rekonstruktor (metode kelas

# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_60) mengembalikan objek penyedia buffer jika memiliki tipe yang tepat. Ini adalah cara mudah untuk mensimulasikan perilaku zero-copy pada contoh mainan ini

Di sisi konsumen, kita dapat mengasinkan objek tersebut dengan cara biasa, yang jika tidak diserialisasi akan memberi kita salinan objek asli

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
0

Tetapi jika kita melewatkan buffer_callback dan kemudian mengembalikan buffer yang terakumulasi saat unserializing, kita bisa mendapatkan kembali objek aslinya

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_1

Contoh ini dibatasi oleh fakta yang mengalokasikan memorinya sendiri. Anda tidak dapat membuat instance yang didukung oleh memori objek lain. Namun, tipe data pihak ketiga seperti larik NumPy tidak memiliki batasan ini, dan memungkinkan penggunaan pengawetan tanpa salinan (atau membuat salinan sesedikit mungkin) saat mentransfer antar proses atau sistem yang berbeda

Lihat juga

PEP 574 – Protokol acar 5 dengan data out-of-band

Membatasi Global

Secara default, unpickling akan mengimpor kelas atau fungsi apa pun yang ditemukannya di data pickle. Untuk banyak aplikasi, perilaku ini tidak dapat diterima karena mengizinkan unpickler untuk mengimpor dan menjalankan kode arbitrer. Pertimbangkan saja apa yang dilakukan aliran data acar buatan tangan ini saat dimuat

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_2

Dalam contoh ini, unpickler mengimpor fungsi dan kemudian menerapkan argumen string "echo hello world". Meskipun contoh ini tidak menyinggung, tidak sulit membayangkan contoh yang dapat merusak sistem Anda

Untuk alasan ini, Anda mungkin ingin mengontrol apa yang akan dihilangkan dengan penyesuaian. Tidak seperti namanya, dipanggil setiap kali global (i. e. , kelas atau fungsi) diminta. Dengan demikian dimungkinkan untuk sepenuhnya melarang global atau membatasi mereka ke subset yang aman

Berikut adalah contoh unpickler yang memungkinkan hanya beberapa kelas aman dari modul yang akan dimuat

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_3

Contoh penggunaan unpickler kami berfungsi sebagaimana mestinya

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_4

Seperti yang ditunjukkan oleh contoh kami, Anda harus berhati-hati dengan apa yang Anda izinkan untuk tidak diawetkan. Oleh karena itu, jika keamanan menjadi perhatian, Anda mungkin ingin mempertimbangkan alternatif seperti menyusun API di atau solusi pihak ketiga

Pertunjukan

Versi terbaru dari protokol pickle (dari protokol 2 dan ke atas) menampilkan pengkodean biner yang efisien untuk beberapa fitur umum dan tipe bawaan. Juga, modul ini memiliki pengoptimal transparan yang ditulis dalam C

Contoh

Untuk kode yang paling sederhana, gunakan fungsi dan

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
5

Contoh berikut membaca data acar yang dihasilkan

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_6

Lihat juga

Modul

Registrasi konstruktor antarmuka acar untuk jenis ekstensi

Modul

Alat untuk bekerja dengan dan menganalisis data acar

Modul

Database objek yang diindeks;

Modul

Penyalinan objek yang dangkal dan dalam

Modul

Serialisasi kinerja tinggi dari tipe bawaan

Catatan kaki

Jangan bingung ini dengan modul

Inilah sebabnya mengapa fungsi tidak dapat diasamkan. semua

def save(obj):
    return (obj.__class__, obj.__dict__)

def restore(cls, attributes):
    obj = cls.__new__(cls)
    obj.__dict__.update(attributes)
    return obj
_26 fungsi memiliki nama yang sama.
# Simple example presenting how persistent ID can be used to pickle
# external objects by reference.

import pickle
import sqlite3
from collections import namedtuple

# Simple class representing a record in our database.
MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):

    def persistent_id(self, obj):
        # Instead of pickling MemoRecord as a regular class instance, we emit a
        # persistent ID.
        if isinstance(obj, MemoRecord):
            # Here, our persistent ID is simply a tuple, containing a tag and a
            # key, which refers to a specific record in the database.
            return ("MemoRecord", obj.key)
        else:
            # If obj does not have a persistent ID, return None. This means obj
            # needs to be pickled as usual.
            return None


class DBUnpickler(pickle.Unpickler):

    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        # This method is invoked whenever a persistent ID is encountered.
        # Here, pid is the tuple returned by DBPickler.
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            # Fetch the referenced record from the database and return it.
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        else:
            # Always raises an error if you cannot return the correct object.
            # Otherwise, the unpickler will think None is the object referenced
            # by the persistent ID.
            raise pickle.UnpicklingError("unsupported persistent object")


def main():
    import io
    import pprint

    # Initialize and populate our database.
    conn = sqlite3.connect(":memory:")
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
    tasks = (
        'give food to fish',
        'prepare group meeting',
        'fight with a zebra',
        )
    for task in tasks:
        cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

    # Fetch the records to be pickled.
    cursor.execute("SELECT * FROM memos")
    memos = [MemoRecord(key, task) for key, task in cursor]
    # Save the records using our custom DBPickler.
    file = io.BytesIO()
    DBPickler(file).dump(memos)

    print("Pickled records:")
    pprint.pprint(memos)

    # Update a record, just for good measure.
    cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

    # Load the records from the pickle data stream.
    file.seek(0)
    memos = DBUnpickler(file, conn).load()

    print("Unpickled records:")
    pprint.pprint(memos)


if __name__ == '__main__':
    main()
_80

Pengecualian yang diajukan kemungkinan besar akan menjadi atau tetapi bisa juga sesuatu yang lain

Modul menggunakan protokol ini untuk operasi penyalinan dangkal dan dalam

Keterbatasan karakter alfanumerik disebabkan oleh fakta bahwa ID persisten dalam protokol 0 dibatasi oleh karakter baris baru. Oleh karena itu, jika karakter baris baru apa pun muncul di ID persisten, data acar yang dihasilkan menjadi tidak dapat dibaca

Bagaimana Anda mengambil file biner dengan Python?

Proses memuat file acar kembali ke program Python serupa dengan yang Anda lihat sebelumnya. gunakan fungsi open() lagi, tapi kali ini dengan 'rb' sebagai argumen kedua (bukan wb ) . R adalah singkatan dari mode baca dan b adalah singkatan dari mode biner. Anda akan membaca file biner. Tetapkan ini ke file.

Bisakah saya menambahkan data ke file acar?

seek(0)– Catatan acar dapat digabungkan menjadi file , jadi ya, Anda bisa acar saja. load(f) beberapa kali, tetapi file itu sendiri tidak diindeks dengan cara yang memungkinkan Anda mencari catatan tertentu.

Apa itu pengawetan dalam file biner?

“Pickling” adalah proses di mana hierarki objek Python diubah menjadi aliran byte , dan “unpickling” adalah operasi kebalikannya, .

Metode modul pickle mana yang digunakan untuk menulis ke biner?

dump(object , file_handler) - digunakan untuk menulis objek apapun ke file biner.