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 PythonTrong 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
7$ 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]}
- Cách sử dụng mô-đun Python
7 để tuần tự hóa hệ thống phân cấp đố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]}
- 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
- Mô-đun
0# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[square]
- Mô-đun
1# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[square]
- Mô-đun
7$ 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]}
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ệuCó 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
8# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[square]
9# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[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
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$ 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
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ạnGhi 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 PythonVì 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
Không sử dụng mô-đun
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# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[square]
Mô-đun
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# pickling_error.py import pickle square = lambda x : x * x my_pickle = pickle.dumps[square]
Mô-đun Python
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$ 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]}
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
$ 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]}
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
5# pickling_dill.py import dill square = lambda x: x * x my_pickle = dill.dumps[square] print[my_pickle]
6# pickling_dill.py import dill square = lambda x: x * x my_pickle = dill.dumps[square] print[my_pickle]
7# pickling_dill.py import dill square = lambda x: x * x my_pickle = dill.dumps[square] print[my_pickle]
8# pickling_dill.py import dill square = lambda x: x * x my_pickle = dill.dumps[square] print[my_pickle]
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ỗiXem 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
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$ 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>>> 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>>> square = lambda x : x * x >>> a = square[35] >>> import math >>> b = math.sqrt[484] >>> import dill >>> dill.dump_session['test.pkl'] >>> exit[]
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
5Cuố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
$ 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]}
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- 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
- Giao thức phiên bản 1 là định dạng nhị phân đầu tiên
- Giao thức phiên bản 2 đã được giới thiệu trong Python 2. 3
- 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
- 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
- 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
6Loại bỏ các quảng cáoCá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ácNế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
9Mô-đ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ênNế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ạnGhi 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]}
7Mặ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
9Vì 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ụngTrong 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ọnNế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]}
0Như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]}
1Bằ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ọnLoại bỏ các quảng cáoNé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ẩnTrong 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]}
2Khi 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
$ 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]}
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ạngTuy 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ạoVí 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]}
3Trong 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]}
32Bằ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]}
5Nế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]}
6Vì 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ậyLoại bỏ các quảng cáoPhầ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ểmTrong 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
7$ 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]}
- Cách sử dụng mô-đun Python
7 để tuần tự hóa hệ thống phân cấp đố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]}
- 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ìnhNế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ề DavideMỗ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ẻ EmailBà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