Lưu danh sách trong python dưa chua

Mô-đun thực hiện các giao thức nhị phân để tuần tự hóa và hủy tuần tự hóa cấu trúc đối tượng Python. “Pickling” là quá trình theo đó hệ thống phân cấp đối tượng Python được chuyển đổi thành luồng byte và “unpickling” là thao tác nghịch đảo, theo đó luồng byte [từ a hoặc ] được chuyển đổi trở lại thành hệ thống phân cấp đối tượng. Pickling [và unpickling] còn được gọi là “serialization”, “marshalling” hoặc “flattening”;

Cảnh báo

Mô-đun

def save[obj]:
    return [obj.__class__, obj.__dict__]

def restore[cls, attributes]:
    obj = cls.__new__[cls]
    obj.__dict__.update[attributes]
    return obj
7 không an toàn. Chỉ giải nén dữ liệu mà bạn tin tưởng

Có thể xây dựng dữ liệu dưa chua độc hại sẽ thực thi mã tùy ý trong quá trình giải nén. Không bao giờ giải nén dữ liệu có thể đến từ một nguồn không đáng tin cậy hoặc có thể đã bị giả mạo

Cân nhắc việc ký dữ liệu nếu bạn cần đảm bảo rằng dữ liệu không bị giả mạo

Các định dạng tuần tự hóa an toàn hơn như có thể phù hợp hơn nếu bạn đang xử lý dữ liệu không đáng tin cậy. Thấy

Mối quan hệ với các mô-đun Python khác

So sánh với
# 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 có một mô-đun tuần tự hóa nguyên thủy hơn được gọi là , nhưng nói chung phải luôn là cách ưu tiên để tuần tự hóa các đối tượng Python. tồn tại chủ yếu để hỗ trợ các tệp

# 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 của Python

Mô-đun khác với một số cách quan trọng

  • Mô-đun theo dõi các đối tượng mà nó đã đánh số thứ tự, để sau này các tham chiếu đến cùng một đối tượng sẽ không được đánh số thứ tự nữa. không làm điều này

    Điều này có ý nghĩa đối với cả đối tượng đệ quy và chia sẻ đối tượng. Các đối tượng đệ quy là các đối tượng chứa các tham chiếu đến chính chúng. Những thứ này không được xử lý bởi nguyên soái và trên thực tế, việc cố gắng sắp xếp theo thứ tự các đối tượng đệ quy sẽ làm hỏng trình thông dịch Python của bạn. Chia sẻ đối tượng xảy ra khi có nhiều tham chiếu đến cùng một đối tượng ở các vị trí khác nhau trong hệ thống phân cấp đối tượng được tuần tự hóa. lưu trữ các đối tượng như vậy chỉ một lần và đảm bảo rằng tất cả các tham chiếu khác trỏ đến bản sao chính. Các đối tượng được chia sẻ vẫn được chia sẻ, điều này có thể rất quan trọng đối với các đối tượng có thể thay đổi

  • không thể được sử dụng để tuần tự hóa các lớp do người dùng định nghĩa và các thể hiện của chúng. có thể lưu và khôi phục các thể hiện của lớp một cách minh bạch, tuy nhiên định nghĩa lớp phải có thể nhập được và nằm trong cùng một mô-đun như khi đối tượng được lưu trữ

  • Định dạng tuần tự hóa không được đảm bảo để có thể di chuyển trên các phiên bản Python. Bởi vì công việc chính của nó trong cuộc sống là hỗ trợ các tệp

    # 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, nên những người triển khai Python có quyền thay đổi định dạng tuần tự hóa theo những cách không tương thích ngược nếu có nhu cầu. Định dạng tuần tự hóa được đảm bảo tương thích ngược trên các bản phát hành Python miễn là một giao thức pickle tương thích được chọn và mã pickling và unpickling xử lý các khác biệt về loại Python 2 đến Python 3 nếu dữ liệu của bạn vượt qua ranh giới ngôn ngữ thay đổi phá vỡ duy nhất đó

So sánh với
# 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

Có sự khác biệt cơ bản giữa các giao thức pickle và JSON [Ký hiệu đối tượng JavaScript]

  • JSON là định dạng tuần tự hóa văn bản [nó xuất ra văn bản unicode, mặc dù sau đó hầu hết thời gian nó được mã hóa thành

    f = io.BytesIO[]
    p = pickle.Pickler[f]
    p.dispatch_table = copyreg.dispatch_table.copy[]
    p.dispatch_table[SomeClass] = reduce_SomeClass
    
    8], trong khi pickle là định dạng tuần tự hóa nhị phân;

  • JSON có thể đọc được bằng con người, trong khi dưa chua thì không;

  • JSON có thể tương tác và được sử dụng rộng rãi bên ngoài hệ sinh thái Python, trong khi dưa chua là dành riêng cho Python;

  • Theo mặc định, JSON chỉ có thể đại diện cho một tập hợp con của các loại tích hợp Python và không có lớp tùy chỉnh nào;

  • Không giống như dưa chua, bản thân việc giải tuần tự hóa JSON không đáng tin cậy không tạo ra lỗ hổng thực thi mã tùy ý

Xem thêm

mô-đun. một mô-đun thư viện tiêu chuẩn cho phép tuần tự hóa và giải tuần tự hóa JSON

Định dạng luồng dữ liệu

Định dạng dữ liệu được sử dụng là dành riêng cho Python. Điều này có lợi thế là không có hạn chế nào được áp đặt bởi các tiêu chuẩn bên ngoài như JSON hoặc XDR [không thể đại diện cho việc chia sẻ con trỏ];

Theo mặc định, định dạng dữ liệu sử dụng biểu diễn nhị phân tương đối nhỏ gọn. Nếu cần các đặc điểm kích thước tối ưu, bạn có thể nén dữ liệu được chọn một cách hiệu quả.

Mô-đun chứa các công cụ để phân tích các luồng dữ liệu được tạo bởi. mã nguồn có nhiều nhận xét về opcode được sử dụng bởi các giao thức pickle

Hiện tại có 6 giao thức khác nhau có thể được sử dụng để tẩy. Giao thức được sử dụng càng cao thì phiên bản Python cần thiết để đọc dưa chua được tạo ra càng mới

  • Giao thức phiên bản 0 là giao thức gốc “con người có thể đọc được” và tương thích ngược với các phiên bản Python cũ hơn

  • Giao thức phiên bản 1 là một định dạng nhị phân cũ cũng tương thích với các phiên bản Python cũ hơn

  • Giao thức phiên bản 2 đã được giới thiệu trong Python 2. 3. Nó cung cấp hiệu quả hơn nhiều ngâm của. Tham khảo PEP 307 để biết thông tin về các cải tiến do giao thức 2 mang lại

  • Giao thức phiên bản 3 đã được thêm vào Python 3. 0. Nó có hỗ trợ rõ ràng cho các đối tượng và Python 2 không thể giải nén. x. Đây là giao thức mặc định trong Python 3. 0–3. 7

  • Giao thức phiên bản 4 đã được thêm vào Python 3. 4. Nó thêm hỗ trợ cho các đối tượng rất lớn, chọn nhiều loại đối tượng hơn và một số tối ưu hóa định dạng dữ liệu. Nó là giao thức mặc định bắt đầu với Python 3. 8. Tham khảo PEP 3154 để biết thông tin về các cải tiến do giao thức 4 mang lại

  • Giao thức phiên bản 5 đã được thêm vào Python 3. 8. Nó bổ sung hỗ trợ cho dữ liệu ngoài băng tần và tăng tốc cho dữ liệu trong băng tần. Tham khảo PEP 574 để biết thông tin về các cải tiến do giao thức 5 mang lại

Ghi chú

Tuần tự hóa là một khái niệm nguyên thủy hơn là kiên trì; . Mô-đun có thể chuyển đổi một đối tượng phức tạp thành luồng byte và nó có thể chuyển đổi luồng byte thành một đối tượng có cùng cấu trúc bên trong. Có lẽ điều rõ ràng nhất cần làm với các luồng byte này là ghi chúng vào một tệp, nhưng cũng có thể gửi chúng qua mạng hoặc lưu trữ chúng trong cơ sở dữ liệu. Mô-đun này cung cấp một giao diện đơn giản để chọn và bỏ chọn các đối tượng trên các tệp cơ sở dữ liệu kiểu DBM

Giao diện mô-đun

Để tuần tự hóa một hệ thống phân cấp đối tượng, bạn chỉ cần gọi hàm. Tương tự, để hủy tuần tự hóa luồng dữ liệu, bạn gọi hàm. Tuy nhiên, nếu bạn muốn kiểm soát nhiều hơn đối với tuần tự hóa và hủy tuần tự hóa, bạn có thể tạo một hoặc một đối tượng tương ứng

Mô-đun cung cấp các hằng số sau

dưa chua. HIGHEST_PROTOCOL

Một số nguyên, cao nhất hiện có. Giá trị này có thể được chuyển dưới dạng giá trị giao thức cho các hàm và cũng như hàm tạo

dưa chua. DEFAULT_PROTOCOL

Một số nguyên, mặc định được sử dụng để tẩy. Có thể ít hơn. Hiện tại giao thức mặc định là 4, được giới thiệu lần đầu trong Python 3. 4 và không tương thích với các phiên bản trước

Đã thay đổi trong phiên bản 3. 0. Giao thức mặc định là 3.

Đã thay đổi trong phiên bản 3. 8. Giao thức mặc định là 4.

Mô-đun cung cấp các chức năng sau để làm cho quá trình ngâm thuận tiện hơn

dưa chua. kết xuất[obj , tệp, protocol=None, *, fix_imports=True, buffer_callback=None]

Viết biểu diễn ngâm của đối tượng obj vào tệp đang mở. Điều này tương đương với

copyreg.pickle[SomeClass, reduce_SomeClass]
f = io.BytesIO[]
p = pickle.Pickler[f]
9

Tệp đối số, giao thức, fix_imports và buffer_callback có cùng ý nghĩa như trong hàm tạo

Đã thay đổi trong phiên bản 3. 8. Đã thêm đối số buffer_callback.

dưa chua. kết xuất[obj , giao thức=None, *, fix_imports=True, buffer_callback=None]

Trả lại biểu diễn đã chọn của đối tượng obj dưới dạng một đối tượng, thay vì ghi nó vào một tệp

Giao thức đối số, fix_imports và buffer_callback có cùng ý nghĩa như trong hàm tạo

Đã thay đổi trong phiên bản 3. 8. Đã thêm đối số buffer_callback.

dưa chua. tải[tệp , *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None]

Đọc biểu diễn được chọn của một đối tượng từ tệp đang mở và trả về cấu trúc phân cấp đối tượng được hoàn nguyên được chỉ định trong đó. Điều này tương đương với

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

Phiên bản giao thức của dưa chua được phát hiện tự động, vì vậy không cần đối số giao thức. Các byte vượt qua biểu diễn ngâm của đối tượng bị bỏ qua

Tệp đối số, fix_imports, mã hóa, lỗi, nghiêm ngặt và bộ đệm có cùng ý nghĩa như trong hàm tạo

Đã thay đổi trong phiên bản 3. 8. Đã thêm đối số bộ đệm.

dưa chua. tải[dữ liệu , /, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None]

Trả về cấu trúc phân cấp đối tượng được hoàn nguyên của dữ liệu đại diện đã chọn của một đối tượng. dữ liệu phải là một

Phiên bản giao thức của dưa chua được phát hiện tự động, vì vậy không cần đối số giao thức. Các byte vượt qua biểu diễn ngâm của đối tượng bị bỏ qua

Các đối số fix_imports, mã hóa, lỗi, nghiêm ngặt và bộ đệm có cùng ý nghĩa như trong hàm tạo

Đã thay đổi trong phiên bản 3. 8. Đã thêm đối số bộ đệm.

Mô-đun xác định ba trường hợp ngoại lệ

ngoại lệ dưa chua. Lỗi dưa chua

Lớp cơ sở chung cho các ngoại lệ tẩy khác. Nó kế thừa

ngoại lệ dưa chua. Lỗi tẩy

Lỗi xuất hiện khi một đối tượng không thể chọn được gặp phải bởi. Nó kế thừa

Tham khảo để biết những loại đồ vật nào có thể ngâm được

ngoại lệ dưa chua. Lỗi bỏ chọn

Lỗi xuất hiện khi có sự cố khi giải nén một đối tượng, chẳng hạn như hỏng dữ liệu hoặc vi phạm bảo mật. Nó kế thừa

Lưu ý rằng các ngoại lệ khác cũng có thể được nêu ra trong quá trình bỏ chọn, bao gồm [nhưng không nhất thiết giới hạn ở] AttributeError, EOFError, ImportError và IndexError

Mô-đun xuất ba lớp, và

lớp dưa chua. Pickler[tệp , giao thức=None, *, fix_imports=True, buffer_callback=None]

Điều này cần một tệp nhị phân để ghi luồng dữ liệu dưa chua

Đối số giao thức tùy chọn, một số nguyên, báo cho bộ chọn sử dụng giao thức đã cho; . Nếu không được chỉ định, mặc định là. Nếu một số âm được chỉ định, được chọn

Đối số tệp phải có phương thức write[] chấp nhận một đối số byte đơn. Do đó, nó có thể là một tệp trên đĩa được mở để ghi nhị phân, một thể hiện hoặc bất kỳ đối tượng tùy chỉnh nào khác đáp ứng giao diện này

Nếu fix_imports là true và giao thức nhỏ hơn 3, pickle sẽ cố gắng ánh xạ tên Python 3 mới sang tên mô-đun cũ được sử dụng trong Python 2, để có thể đọc được luồng dữ liệu pickle bằng Python 2

Nếu buffer_callback là Không có [mặc định], chế độ xem bộ đệm được tuần tự hóa thành tệp như một phần của luồng pickle

Nếu buffer_callback không phải là Không, thì nó có thể được gọi bất kỳ số lần nào với chế độ xem bộ đệm. Nếu cuộc gọi lại trả về một giá trị sai [chẳng hạn như Không], bộ đệm đã cho là; . e. bên trong dòng dưa chua

Đó là lỗi nếu buffer_callback không phải là Không có và giao thức là Không có hoặc nhỏ hơn 5

Đã thay đổi trong phiên bản 3. 8. Đã thêm đối số buffer_callback.

kết xuất[obj]

Viết biểu diễn được chọn của obj vào đối tượng tệp đang mở được cung cấp trong hàm tạo

persistent_id[obj]

Không làm gì theo mặc định. Điều này tồn tại để một lớp con có thể ghi đè lên nó

Nếu trả về

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 được ngâm như bình thường. Bất kỳ giá trị nào khác sẽ tạo ra giá trị được trả về dưới dạng ID liên tục cho obj. Ý nghĩa của ID liên tục này phải được xác định bởi. Lưu ý rằng giá trị được trả về không thể có ID cố định

Xem để biết chi tiết và ví dụ về cách sử dụng

công văn_table

Bảng điều phối của đối tượng bộ chọn là sổ đăng ký các hàm rút gọn thuộc loại có thể được khai báo bằng cách sử dụng. Nó là một ánh xạ có khóa là các lớp và có giá trị là các hàm rút gọn. Một hàm rút gọn nhận một đối số duy nhất của lớp được liên kết và phải tuân theo cùng một giao diện như một phương thức

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

Theo mặc định, một đối tượng bộ chọn sẽ không có thuộc tính và thay vào đó, nó sẽ sử dụng bảng điều phối chung do mô-đun quản lý. Tuy nhiên, để tùy chỉnh phần tẩy cho một đối tượng bộ chọn cụ thể, người ta có thể đặt thuộc tính thành một đối tượng giống như dict. Ngoài ra, nếu một lớp con của có thuộc tính thì thuộc tính này sẽ được sử dụng làm bảng điều phối mặc định cho các thể hiện của lớp đó

Xem các ví dụ sử dụng

Mới trong phiên bản 3. 3

reducer_override[obj]

Bộ giảm tốc đặc biệt có thể được định nghĩa trong các lớp con. Phương pháp này được ưu tiên hơn bất kỳ bộ giảm tốc nào trong. Nó phải phù hợp với cùng một giao diện như một phương pháp

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 và có thể tùy ý trả lại
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 = 5:
            return type[self]._reconstruct, [PickleBuffer[self],], None
        else:
            # PickleBuffer is forbidden with pickle protocols = 5:
            return type[self]._reconstruct, [PickleBuffer[self],], None
        else:
            # PickleBuffer is forbidden with pickle protocols = 5:
            return type[self]._reconstruct, [PickleBuffer[self],], None
        else:
            # PickleBuffer is forbidden with pickle protocols >> 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!'

Giảm bớt tùy chỉnh cho các loại, chức năng và các đối tượng khác

Mới trong phiên bản 3. 8

Đôi khi, có thể không đủ linh hoạt. Cụ thể, chúng tôi có thể muốn tùy chỉnh việc chọn lọc dựa trên một tiêu chí khác ngoài loại của đối tượng hoặc chúng tôi có thể muốn tùy chỉnh việc chọn lọc các hàm và lớp

Đối với những trường hợp đó, có thể phân lớp từ lớp và thực hiện một phương thức. Phương thức này có thể trả về một bộ rút gọn tùy ý [xem

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]. Ngoài ra, nó có thể trả lại
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 = 5:
            return type[self]._reconstruct, [PickleBuffer[self],], None
        else:
            # PickleBuffer is forbidden with pickle protocols 

Chủ Đề