Cách dùng trăn muối

Là nhà phát triển, đôi khi bạn có thể cần gửi các hệ thống phân cấp đối tượng phức tạp qua mạng hoặc lưu trạng thái bên trong của đối tượng vào đĩa hoặc cơ sở dữ liệu để sử dụng sau này. Để thực hiện điều này, bạn có thể sử dụng một quy trình có tên là tuần tự hóa, được thư viện chuẩn hỗ trợ đầy đủ nhờ mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python

Trong hướng dẫn này, bạn sẽ học

  • Ý nghĩa của việc tuần tự hóa và giải tuần tự hóa một đối tượng
  • Những mô-đun nào bạn có thể sử dụng để tuần tự hóa các đối tượng trong Python
  • Những loại đối tượng nào có thể được tuần tự hóa với mô-đun Python
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7
  • Cách sử dụng mô-đun Python
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7 để tuần tự hóa hệ thống phân cấp đối tượng
  • Những rủi ro là gì khi giải tuần tự hóa một đối tượng từ một nguồn không đáng tin cậy

Hãy ngâm chua

Tiền thưởng miễn phí. 5 Suy nghĩ về Làm chủ Python, một khóa học miễn phí dành cho các nhà phát triển Python cho bạn thấy lộ trình và tư duy mà bạn sẽ cần để đưa các kỹ năng Python của mình lên một tầm cao mới

Tuần tự hóa trong Python

Quá trình tuần tự hóa là một cách để chuyển đổi cấu trúc dữ liệu thành dạng tuyến tính có thể được lưu trữ hoặc truyền qua mạng

Trong Python, tuần tự hóa cho phép bạn lấy một cấu trúc đối tượng phức tạp và chuyển đổi nó thành một luồng byte có thể được lưu vào đĩa hoặc gửi qua mạng. Bạn cũng có thể thấy quá trình này được gọi là sắp xếp. Quá trình đảo ngược, lấy một luồng byte và chuyển đổi nó trở lại thành cấu trúc dữ liệu, được gọi là giải tuần tự hóa hoặc sắp xếp lại

Tuần tự hóa có thể được sử dụng trong nhiều tình huống khác nhau. Một trong những cách sử dụng phổ biến nhất là lưu trạng thái của mạng thần kinh sau giai đoạn đào tạo để bạn có thể sử dụng nó sau này mà không phải thực hiện lại quá trình đào tạo

Python cung cấp ba mô-đun khác nhau trong thư viện chuẩn cho phép bạn tuần tự hóa và giải tuần tự hóa các đối tượng

  1. Mô-đun
    # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    0
  2. Mô-đun
    # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    1
  3. Mô-đun
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7

Ngoài ra, Python hỗ trợ XML, mà bạn cũng có thể sử dụng để tuần tự hóa các đối tượng

Mô-đun

# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
0 là mô-đun lâu đời nhất trong ba mô-đun được liệt kê ở trên. Nó tồn tại chủ yếu để đọc và ghi mã byte đã biên dịch của mô-đun Python hoặc tệp
# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
4 mà bạn nhận được khi trình thông dịch nhập mô-đun Python. Vì vậy, mặc dù bạn có thể sử dụng
# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
0 để sắp xếp theo thứ tự một số đối tượng của mình, nhưng điều đó không được khuyến nghị

Mô-đun

# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
1 là mô-đun mới nhất trong ba mô-đun. Nó cho phép bạn làm việc với các tệp JSON tiêu chuẩn. JSON là một định dạng rất thuận tiện và được sử dụng rộng rãi để trao đổi dữ liệu

Có một số lý do để chọn định dạng JSON. Nó có thể đọc được bằng con người và không phụ thuộc vào ngôn ngữ, đồng thời nhẹ hơn XML. Với mô-đun

# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
1, bạn có thể tuần tự hóa và giải tuần tự hóa một số loại Python tiêu chuẩn

  • # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    8
  • # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    9
  • $ python pickling_error.py
    Traceback [most recent call last]:
      File "pickling_error.py", line 6, in 
        my_pickle = pickle.dumps[square]
    _pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed
    
    2
  • $ python pickling_error.py
    Traceback [most recent call last]:
      File "pickling_error.py", line 6, in 
        my_pickle = pickle.dumps[square]
    _pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed
    
    3
  • $ python pickling_error.py
    Traceback [most recent call last]:
      File "pickling_error.py", line 6, in 
        my_pickle = pickle.dumps[square]
    _pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed
    
    4
  • $ python pickling_error.py
    Traceback [most recent call last]:
      File "pickling_error.py", line 6, in 
        my_pickle = pickle.dumps[square]
    _pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed
    
    5

Mô-đun Python

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 là một cách khác để tuần tự hóa và giải tuần tự hóa các đối tượng trong Python. Nó khác với mô-đun
# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
1 ở chỗ nó tuần tự hóa các đối tượng ở định dạng nhị phân, có nghĩa là kết quả không thể đọc được bằng con người. Tuy nhiên, nó cũng nhanh hơn và nó hoạt động với nhiều loại Python hơn ngay lập tức, bao gồm cả các đối tượng được xác định tùy chỉnh của bạn

Ghi chú. Từ giờ trở đi, bạn sẽ thấy các thuật ngữ pickling và unpickling được sử dụng để chỉ việc tuần tự hóa và giải tuần tự hóa với mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python

Vì vậy, bạn có một số cách khác nhau để tuần tự hóa và giải tuần tự hóa các đối tượng trong Python. Nhưng cái nào bạn nên sử dụng? . Tất cả phụ thuộc vào trường hợp sử dụng của bạn

Dưới đây là ba hướng dẫn chung để quyết định nên sử dụng phương pháp nào

  1. Không sử dụng mô-đun

    # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    0. Nó được sử dụng chủ yếu bởi trình thông dịch và tài liệu chính thức cảnh báo rằng những người bảo trì Python có thể sửa đổi định dạng theo những cách không tương thích ngược

  2. Mô-đun

    # pickling_error.py
    import pickle
    
    square = lambda x : x * x
    my_pickle = pickle.dumps[square]
    
    1 và XML là những lựa chọn tốt nếu bạn cần khả năng tương tác với các ngôn ngữ khác nhau hoặc định dạng mà con người có thể đọc được

  3. Mô-đun Python

    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7 là lựa chọn tốt hơn cho tất cả các trường hợp sử dụng còn lại. Nếu bạn không cần định dạng mà con người có thể đọc được hoặc định dạng có thể tương tác tiêu chuẩn hoặc nếu bạn cần sắp xếp theo thứ tự các đối tượng tùy chỉnh, thì hãy sử dụng
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7

Loại bỏ các quảng cáo

Bên trong Mô-đun
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python

Mô-đun Python

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 về cơ bản bao gồm bốn phương thức

  1. # pickling_dill.py
    import dill
    
    square = lambda x: x * x
    my_pickle = dill.dumps[square]
    print[my_pickle]
    
    5
  2. # pickling_dill.py
    import dill
    
    square = lambda x: x * x
    my_pickle = dill.dumps[square]
    print[my_pickle]
    
    6
  3. # pickling_dill.py
    import dill
    
    square = lambda x: x * x
    my_pickle = dill.dumps[square]
    print[my_pickle]
    
    7
  4. # pickling_dill.py
    import dill
    
    square = lambda x: x * x
    my_pickle = dill.dumps[square]
    print[my_pickle]
    
    8

Hai phương pháp đầu tiên được sử dụng trong quá trình tẩy và hai phương pháp còn lại được sử dụng trong quá trình tẩy. Sự khác biệt duy nhất giữa

# pickling_dill.py
import dill

square = lambda x: x * x
my_pickle = dill.dumps[square]
print[my_pickle]
9 và
$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
0 là tệp đầu tiên tạo một tệp chứa kết quả đánh số thứ tự, trong khi tệp thứ hai trả về một chuỗi

Để phân biệt giữa

$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
0 với
# pickling_dill.py
import dill

square = lambda x: x * x
my_pickle = dill.dumps[square]
print[my_pickle]
9, bạn nên nhớ rằng ____31_______3 ở cuối tên hàm là viết tắt của ____13_______3. Khái niệm tương tự cũng áp dụng cho
$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
5 và
$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
6. Cái đầu tiên đọc một tệp để bắt đầu quá trình giải nén và cái thứ hai hoạt động trên một chuỗi

Xem xét ví dụ sau. Giả sử bạn có một lớp được xác định tùy chỉnh có tên là

$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
7 với một số thuộc tính khác nhau, mỗi thuộc tính thuộc một loại khác nhau

  • $ python pickling_dill.py
    b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
    
    8
  • $ python pickling_dill.py
    b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
    
    9
  • >>> square = lambda x : x * x
    >>> a = square[35]
    >>> import math
    >>> b = math.sqrt[484]
    >>> import dill
    >>> dill.dump_session['test.pkl']
    >>> exit[]
    
    0
  • >>> square = lambda x : x * x
    >>> a = square[35]
    >>> import math
    >>> b = math.sqrt[484]
    >>> import dill
    >>> dill.dump_session['test.pkl']
    >>> exit[]
    
    1
  • >>> square = lambda x : x * x
    >>> a = square[35]
    >>> import math
    >>> b = math.sqrt[484]
    >>> import dill
    >>> dill.dump_session['test.pkl']
    >>> exit[]
    
    2

Ví dụ dưới đây cho thấy cách bạn có thể khởi tạo lớp và chọn cá thể để nhận một chuỗi đơn giản. Sau khi chọn lớp, bạn có thể thay đổi giá trị của các thuộc tính của nó mà không ảnh hưởng đến chuỗi đã chọn. Sau đó, bạn có thể giải nén chuỗi đã chọn trong một biến khác, khôi phục một bản sao chính xác của lớp đã chọn trước đó

# pickling.py
import pickle

class example_class:
    a_number = 35
    a_string = "hey"
    a_list = [1, 2, 3]
    a_dict = {"first": "a", "second": 2, "third": [1, 2, 3]}
    a_tuple = [22, 23]

my_object = example_class[]

my_pickled_object = pickle.dumps[my_object]  # Pickling the object
print[f"This is my pickled object:\n{my_pickled_object}\n"]

my_object.a_dict = None

my_unpickled_object = pickle.loads[my_pickled_object]  # Unpickling the object
print[
    f"This is a_dict of the unpickled object:\n{my_unpickled_object.a_dict}\n"]

Trong ví dụ trên, bạn tạo một số đối tượng khác nhau và sắp xếp chúng theo thứ tự với

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7. Điều này tạo ra một chuỗi duy nhất với kết quả được tuần tự hóa

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}

Quá trình tẩy kết thúc chính xác, lưu trữ toàn bộ phiên bản của bạn trong chuỗi này.

>>> square = lambda x : x * x
>>> a = square[35]
>>> import math
>>> b = math.sqrt[484]
>>> import dill
>>> dill.dump_session['test.pkl']
>>> exit[]
4 Sau khi quá trình pickling kết thúc, bạn sửa đổi đối tượng ban đầu của mình bằng cách đặt thuộc tính
>>> square = lambda x : x * x
>>> a = square[35]
>>> import math
>>> b = math.sqrt[484]
>>> import dill
>>> dill.dump_session['test.pkl']
>>> exit[]
5 thành
$ python pickling_error.py
Traceback [most recent call last]:
  File "pickling_error.py", line 6, in 
    my_pickle = pickle.dumps[square]
_pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed
5

Cuối cùng, bạn giải nén chuỗi thành một thể hiện hoàn toàn mới. Những gì bạn nhận được là một bản sao sâu của cấu trúc đối tượng ban đầu của bạn từ thời điểm quá trình tẩy bắt đầu

Định dạng giao thức của mô-đun Python
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7

Như đã đề cập ở trên, mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 dành riêng cho Python và kết quả của quá trình chọn lọc chỉ có thể được đọc bởi một chương trình Python khác. Nhưng ngay cả khi bạn đang làm việc với Python, điều quan trọng cần biết là mô-đun
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 đã phát triển theo thời gian

Điều này có nghĩa là nếu bạn đã chọn một đối tượng bằng một phiên bản Python cụ thể, thì bạn không thể giải nén nó bằng phiên bản cũ hơn. Khả năng tương thích tùy thuộc vào phiên bản giao thức mà bạn đã sử dụng cho quy trình tẩy

Hiện tại có sáu giao thức khác nhau mà mô-đun Python

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 có thể sử dụng. Phiên bản giao thức càng cao thì trình thông dịch Python càng mới để giải nén

  1. Giao thức phiên bản 0 là phiên bản đầu tiên. Không giống như các giao thức sau này, con người có thể đọc được
  2. Giao thức phiên bản 1 là định dạng nhị phân đầu tiên
  3. Giao thức phiên bản 2 đã được giới thiệu trong Python 2. 3
  4. Giao thức phiên bản 3 đã được thêm vào Python 3. 0. Nó không thể được giải nén bởi Python 2. x
  5. Giao thức phiên bản 4 đã được thêm vào Python 3. 4. Nó có tính năng hỗ trợ cho nhiều loại kích thước và loại đối tượng hơn và là giao thức mặc định bắt đầu với Python 3. 8
  6. Giao thức phiên bản 5 đã được thêm vào Python 3. 8. Nó có tính năng hỗ trợ dữ liệu ngoài băng tần và cải thiện tốc độ cho dữ liệu trong băng tần

Ghi chú. Các phiên bản mới hơn của giao thức cung cấp nhiều tính năng và cải tiến hơn nhưng chỉ giới hạn ở các phiên bản cao hơn của trình thông dịch. Hãy chắc chắn xem xét điều này khi chọn giao thức nào sẽ sử dụng

Để xác định giao thức cao nhất mà thông dịch viên của bạn hỗ trợ, bạn có thể kiểm tra giá trị của thuộc tính

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
1

Để chọn một giao thức cụ thể, bạn cần chỉ định phiên bản giao thức khi bạn gọi

$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
5,
$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
6,
# pickling_dill.py
import dill

square = lambda x: x * x
my_pickle = dill.dumps[square]
print[my_pickle]
9 hoặc
$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'
0. Nếu bạn không chỉ định một giao thức, thì trình thông dịch của bạn sẽ sử dụng phiên bản mặc định được chỉ định trong thuộc tính
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
6

Loại bỏ các quảng cáo

Các loại Picklable và Unpicklable

Bạn đã biết rằng mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python có thể tuần tự hóa nhiều loại hơn mô-đun
# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]
1. Tuy nhiên, không phải cái gì cũng dễ dãi. Danh sách các đối tượng không thể chọn bao gồm các kết nối cơ sở dữ liệu, ổ cắm mạng đã mở, luồng đang chạy và các đối tượng khác

Nếu bạn thấy mình phải đối mặt với một đối tượng không thể chọn được, thì có một số điều bạn có thể làm. Tùy chọn đầu tiên là sử dụng thư viện của bên thứ ba, chẳng hạn như

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9

Mô-đun

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 mở rộng khả năng của
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7. Theo tài liệu chính thức, nó cho phép bạn tuần tự hóa các loại ít phổ biến hơn như hàm có sản lượng, hàm lồng nhau, lambda và nhiều loại khác

Để kiểm tra mô-đun này, bạn có thể thử chọn hàm

>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

2

# pickling_error.py
import pickle

square = lambda x : x * x
my_pickle = pickle.dumps[square]

Nếu bạn cố chạy chương trình này, thì bạn sẽ gặp một ngoại lệ vì mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python không thể tuần tự hóa một hàm
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

2

$ python pickling_error.py
Traceback [most recent call last]:
  File "pickling_error.py", line 6, in 
    my_pickle = pickle.dumps[square]
_pickle.PicklingError: Can't pickle : attribute lookup  on __main__ failed

Bây giờ hãy thử thay thế mô-đun Python

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 bằng
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 để xem có sự khác biệt nào không

# pickling_dill.py
import dill

square = lambda x: x * x
my_pickle = dill.dumps[square]
print[my_pickle]

Nếu bạn chạy mã này, thì bạn sẽ thấy mô-đun

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 tuần tự hóa
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

2 mà không trả về lỗi

$ python pickling_dill.py
b'\x80\x03cdill._dill\n_create_function\nq\x00[cdill._dill\n_load_type\nq\x01X\x08\x00\x00\x00CodeTypeq\x02\x85q\x03Rq\x04[K\x01K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00q\x05N\x85q\x06]X\x01\x00\x00\x00xq\x07\x85q\x08X\x10\x00\x00\x00pickling_dill.pyq\tX\t\x00\x00\x00squareq\nK\x04C\x00q\x0b]]tq\x0cRq\rc__builtin__\n__main__\nh\nNN}q\x0eNtq\x0fRq\x10.'

Một tính năng thú vị khác của

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 là nó thậm chí có thể tuần tự hóa toàn bộ phiên phiên dịch. Đây là một ví dụ

>>>

>>> square = lambda x : x * x
>>> a = square[35]
>>> import math
>>> b = math.sqrt[484]
>>> import dill
>>> dill.dump_session['test.pkl']
>>> exit[]

Trong ví dụ này, bạn khởi động trình thông dịch, nhập mô-đun và xác định hàm

>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

2 cùng với một vài biến khác. Sau đó, bạn nhập mô-đun
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 và gọi
# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]
2 để tuần tự hóa toàn bộ phiên

Nếu mọi thứ đều ổn, thì bạn sẽ nhận được tệp

# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]
3 trong thư mục hiện tại của mình

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl

Bây giờ bạn có thể bắt đầu phiên bản mới của trình thông dịch và tải tệp

# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]
3 để khôi phục phiên cuối cùng của mình

>>>

>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

Câu lệnh

# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]
5 đầu tiên chứng minh rằng trình thông dịch đang ở trạng thái ban đầu. Điều này có nghĩa là bạn cần nhập mô-đun
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 và gọi
# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]
7 để khôi phục phiên phiên dịch được đăng nhiều kỳ của bạn

Ghi chú. Trước khi bạn sử dụng

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 thay vì
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7, hãy nhớ rằng
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 không có trong thư viện chuẩn của trình thông dịch Python và thường chậm hơn
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7

Mặc dù

$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9 cho phép bạn đánh số thứ tự nhiều loại đối tượng hơn so với
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7, nhưng nó không thể giải quyết mọi vấn đề về đánh số thứ tự mà bạn có thể gặp phải. Ví dụ: nếu bạn cần tuần tự hóa một đối tượng chứa kết nối cơ sở dữ liệu, thì bạn sẽ gặp khó khăn vì đó là một đối tượng không thể tuần tự hóa ngay cả đối với
$ ls test.pkl
4 -rw-r--r--@ 1 dave  staff  439 Feb  3 10:52 test.pkl
9

Vì vậy, làm thế nào bạn có thể giải quyết vấn đề này?

Giải pháp trong trường hợp này là loại trừ đối tượng khỏi quá trình tuần tự hóa và khởi tạo lại kết nối sau khi đối tượng được giải tuần tự hóa

Bạn có thể sử dụng

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
05 để xác định những gì nên được đưa vào quy trình ngâm chua. Phương pháp này cho phép bạn chỉ định những gì bạn muốn ngâm. Nếu bạn không ghi đè
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
05, thì phiên bản mặc định của
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
07 sẽ được sử dụng

Trong ví dụ sau, bạn sẽ thấy cách bạn có thể định nghĩa một lớp có nhiều thuộc tính và loại trừ một thuộc tính khỏi quá trình tuần tự hóa với

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
08

# custom_pickling.py

import pickle

class foobar:
    def __init__[self]:
        self.a = 35
        self.b = "test"
        self.c = lambda x: x * x

    def __getstate__[self]:
        attributes = self.__dict__.copy[]
        del attributes['c']
        return attributes

my_foobar_instance = foobar[]
my_pickle_string = pickle.dumps[my_foobar_instance]
my_new_instance = pickle.loads[my_pickle_string]

print[my_new_instance.__dict__]

Trong ví dụ này, bạn tạo một đối tượng có ba thuộc tính. Vì một thuộc tính là

>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ]]]
>>> import dill
>>> dill.load_session['test.pkl']
>>> globals[].items[]
dict_items[[['__name__', '__main__'], ['__doc__', None], ['__package__', None], ['__loader__', ], ['__spec__', None], ['__annotations__', {}], ['__builtins__', ], ['dill', ], ['square', ], ['a', 1225], ['math', ], ['b', 22.0]]]
>>> a
1225
>>> b
22.0
>>> square

2, đối tượng không thể chọn được với mô-đun
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 tiêu chuẩn

Để giải quyết vấn đề này, bạn chỉ định những gì cần ngâm với

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
05. Trước tiên, bạn sao chép toàn bộ
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
07 của phiên bản để có tất cả các thuộc tính được xác định trong lớp, sau đó bạn xóa thủ công thuộc tính
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
13 không thể chọn

Nếu bạn chạy ví dụ này và sau đó giải tuần tự hóa đối tượng, thì bạn sẽ thấy rằng phiên bản mới không chứa thuộc tính

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
13

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
0

Nhưng điều gì sẽ xảy ra nếu bạn muốn thực hiện một số thao tác khởi tạo bổ sung trong khi giải nén, chẳng hạn bằng cách thêm đối tượng

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
13 bị loại trừ trở lại thể hiện đã khử lưu lượng?

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
1

Bằng cách chuyển đối tượng bị loại trừ

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
13 cho
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
16, bạn đảm bảo rằng nó xuất hiện trong
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
07 của chuỗi chưa được chọn

Loại bỏ các quảng cáo

Nén các đối tượng ngâm

Mặc dù định dạng dữ liệu

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 là biểu diễn nhị phân nhỏ gọn của cấu trúc đối tượng, nhưng bạn vẫn có thể tối ưu hóa chuỗi đã chọn của mình bằng cách nén nó bằng
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
21 hoặc
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
22

Để nén chuỗi đã ngâm với

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
21, bạn có thể sử dụng mô-đun
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
24 được cung cấp trong thư viện tiêu chuẩn

Trong ví dụ sau, bạn sẽ lấy một chuỗi, chọn lọc và sau đó nén nó bằng thư viện

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
24

>>>

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
2

Khi sử dụng tính năng nén, hãy nhớ rằng các tệp nhỏ hơn phải trả giá bằng quy trình chậm hơn

Mối quan tâm về bảo mật với Mô-đun
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python

Bây giờ bạn đã biết cách sử dụng mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 để tuần tự hóa và giải tuần tự hóa các đối tượng trong Python. Quá trình tuần tự hóa rất thuận tiện khi bạn cần lưu trạng thái của đối tượng vào đĩa hoặc truyền nó qua mạng

Tuy nhiên, còn một điều nữa bạn cần biết về mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python. Nó không an toàn. Bạn có nhớ cuộc thảo luận của
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
16 không?

Vì vậy, bạn có thể làm gì để giảm rủi ro này?

Đáng buồn thay, không nhiều. Nguyên tắc chung là không bao giờ giải nén dữ liệu đến từ nguồn không đáng tin cậy hoặc được truyền qua mạng không an toàn. Để ngăn chặn các cuộc tấn công trung gian, bạn nên sử dụng các thư viện như

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
30 để ký dữ liệu và đảm bảo dữ liệu không bị giả mạo

Ví dụ sau đây minh họa cách giải nén một dưa chua giả mạo có thể khiến hệ thống của bạn bị kẻ tấn công tấn công, thậm chí cung cấp cho chúng một trình bao từ xa đang hoạt động

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
3

Trong ví dụ này, quy trình giải nén thực thi

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
16, thực thi lệnh Bash để mở shell từ xa tới máy
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
32 trên cổng
$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
33

Đây là cách bạn có thể kiểm tra tập lệnh này một cách an toàn trên máy Mac hoặc hộp Linux của mình. Đầu tiên, mở terminal và sử dụng lệnh

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
34 để lắng nghe kết nối tới cổng 8080

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
4

Đây sẽ là thiết bị đầu cuối của kẻ tấn công. Nếu mọi thứ hoạt động, thì lệnh dường như bị treo

Tiếp theo, mở một thiết bị đầu cuối khác trên cùng một máy tính [hoặc trên bất kỳ máy tính nào khác trong mạng] và thực thi mã Python ở trên để gỡ mã độc. Đảm bảo thay đổi địa chỉ IP trong mã thành địa chỉ IP của thiết bị đầu cuối tấn công của bạn. Trong ví dụ của tôi, địa chỉ IP của kẻ tấn công là

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
32

Bằng cách thực thi mã này, nạn nhân sẽ để lộ trình bao cho kẻ tấn công

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
5

Nếu mọi thứ hoạt động, Bash shell sẽ xuất hiện trên bảng điều khiển tấn công. Bảng điều khiển này hiện có thể hoạt động trực tiếp trên hệ thống bị tấn công

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
6

Vì vậy, hãy để tôi nhắc lại điểm quan trọng này một lần nữa. Không sử dụng mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 để giải tuần tự hóa các đối tượng từ các nguồn không đáng tin cậy

Loại bỏ các quảng cáo

Phần kết luận

Bây giờ bạn đã biết cách sử dụng mô-đun

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7 của Python để chuyển đổi cấu trúc phân cấp đối tượng thành luồng byte có thể được lưu vào đĩa hoặc truyền qua mạng. Bạn cũng biết rằng quy trình deserialization trong Python phải được sử dụng cẩn thận vì việc giải nén thứ gì đó đến từ một nguồn không đáng tin cậy có thể cực kỳ nguy hiểm

Trong hướng dẫn này, bạn đã học

  • Ý nghĩa của việc tuần tự hóa và giải tuần tự hóa một đối tượng
  • Những mô-đun nào bạn có thể sử dụng để tuần tự hóa các đối tượng trong Python
  • Những loại đối tượng nào có thể được tuần tự hóa với mô-đun Python
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7
  • Cách sử dụng mô-đun Python
    $ python pickling.py
    This is my pickled object:
    b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'
    
    This is a_dict of the unpickled object:
    {'first': 'a', 'second': 2, 'third': [1, 2, 3]}
    
    7 để tuần tự hóa hệ thống phân cấp đối tượng
  • Rủi ro của việc gỡ lỗi từ một nguồn không đáng tin cậy là gì

Với kiến ​​thức này, bạn được trang bị tốt để duy trì các đối tượng của mình bằng cách sử dụng mô-đun Python

$ python pickling.py
This is my pickled object:
b'\x80\x03c__main__\nexample_class\nq\x00]\x81q\x01.'

This is a_dict of the unpickled object:
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}
7. Như một phần thưởng bổ sung, bạn đã sẵn sàng giải thích sự nguy hiểm của việc khử lưu huỳnh hóa dưa chua độc hại cho bạn bè và đồng nghiệp của mình

Nếu bạn có bất kỳ câu hỏi nào, hãy để lại bình luận bên dưới hoặc liên hệ với tôi trên Twitter

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Tuần tự hóa các đối tượng bằng Mô-đun pickle Python

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Davide Mastromatteo

Nhà phát triển và biên tập viên của “Góc Python". Người hiến máu, người dùng Apple, nghiện Python và Swift. Người yêu NFL, bóng bầu dục và cờ vua. Thường xuyên đói và ngu ngốc

» Thông tin thêm về Davide

Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Aldren

Geir Arne

Joanna

Gia-cốp

Mike

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Quá trình ngâm trong Python là gì?

“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 ngược lại, .

Làm cách nào để đọc dữ liệu từ tệp dưa chua Python?

Cách cơ bản nhất để đọc tệp dưa chua là sử dụng hàm read_pickle[] . Hàm này lấy tên của tệp dưa chua làm đối số và trả về DataFrame của gấu trúc. Người ta có thể đọc các tệp dưa chua trong Python bằng hàm read_pickle[].

Chủ Đề