Dưa chua Python so với kích thước JSON

Khá nhiều lập trình viên Python ngoài kia đã từng bị hỏng tại một thời điểm và sử dụng mô-đun 'dưa' để ghi các đối tượng ra đĩa

Ưu điểm của việc sử dụng pickle là nó có thể tuần tự hóa khá nhiều đối tượng Python mà không cần phải thêm bất kỳ mã bổ sung nào. Nó cũng thông minh ở chỗ in sẽ chỉ viết ra bất kỳ đối tượng đơn lẻ nào một lần, giúp lưu trữ các cấu trúc đệ quy như biểu đồ một cách hiệu quả. Vì những lý do này, pickle thường là cơ chế tuần tự hóa mặc định trong Python, được sử dụng trong các mô-đun như python-memcached

Tuy nhiên, sử dụng dưa chua vẫn là một ý tưởng tồi tệ nên tránh bất cứ khi nào có thể

Dưa chua chậm

Pickle chậm hơn và tạo ra các giá trị được tuần tự hóa lớn hơn so với hầu hết các lựa chọn thay thế

Để minh họa điều này, tôi tập hợp một điểm chuẩn đơn giản so sánh dưa chua với mô-đun JSON tích hợp, thư viện Apache Thrift và MessagePack. Điểm chuẩn này đo số lượng đối tượng trong một giây mà mỗi thư viện này có thể đọc và ghi. Dữ liệu được sắp xếp theo thứ tự ở đây chỉ là các đối tượng 'Tweet' giả được tạo ngẫu nhiên chỉ chứa bốn trường

Tỷ lệ xê-ri hóa

Kích thước đóng gói

Pickle là người kém hiệu quả rõ ràng ở đây. Ngay cả tiện ích mở rộng 'cPickle' được viết bằng C cũng có tỷ lệ tuần tự hóa bằng khoảng một phần tư so với JSON hoặc Thrift. Pickle cũng tạo ra các giá trị được tuần tự hóa có kích thước gấp đôi Thrift hoặc MessagePack

Tôi đã đặt mã cho điểm chuẩn này trên github cho những người quan tâm

Cập nhật ngày 13 tháng 2Tôi đã thay đổi các biểu đồ ở trên để giải quyết một số vấn đề mà mọi người đã đưa ra. Giao thức dưa chua mặc định chậm, vì vậy tôi đã thêm một phiên bản nhanh hơn. Tôi cũng đã thay đổi điểm chuẩn JSON/MessagePack để hoạt động trên cùng một dữ liệu như Pickle. Các hiệu ứng gần như không mạnh bằng, nhưng ngay cả với cả hai thay đổi, Pickle không phải là một lựa chọn tuyệt vời

Pickle là một rủi ro bảo mật

Một lý do khác để không sử dụng pickle là việc giải nén dữ liệu độc hại có thể gây ra các vấn đề về bảo mật, bao gồm cả việc thực thi mã tùy ý

Một ví dụ mà dũng cảm và ngu ngốc có thể thử là dưới đây. Giải nén dữ liệu ở đó sẽ mở dấu nhắc shell sẽ xóa tất cả các tệp trong thư mục chính của bạn

data  = """cos
system
[S'rm -ri ~'
tR.
"""

pickle.loads[data]

Rất may, lệnh này sẽ nhắc bạn trước khi xóa từng tệp, nhưng một ký tự đơn lẻ của nó sẽ thay đổi dữ liệu khiến nó xóa tất cả các tệp của bạn mà không cần nhắc [

my_dict = {
'name': 'Chris',
'age': 33
}
0]. Tệ hơn nữa, kẻ tấn công có thể sử dụng pickle để truy cập shell từ xa vào máy tính của bạn

Nó không giống như đây là một vấn đề chưa biết. Mô-đun dưa chua thậm chí còn đi kèm với một cảnh báo lớn về điều này ngay trong tài liệu

Cảnh báo. Mô-đun dưa chua không nhằm mục đích bảo mật trước dữ liệu được tạo sai hoặc độc hại. Không bao giờ giải nén dữ liệu nhận được từ nguồn không đáng tin cậy hoặc chưa được xác thực

Nhưng không phải lúc nào dữ liệu của bạn cũng không bị thay đổi kể từ khi bạn viết nó. Ví dụ, kẻ tấn công giành được quyền truy cập vào mạng của bạn, nhưng chưa thể chạy bất kỳ mã nào trên máy chủ của bạn. Nếu bạn đang sử dụng các liên kết bộ nhớ đệm python-memcached mặc định, tất cả những gì kẻ tấn công phải làm là thực hiện cuộc gọi mạng đến máy chủ bộ nhớ đệm của bạn để đặt giá trị dưa chua được chọn cẩn thận và đợi nó được đọc lại trong. Khi quy trình Python của bạn đọc dữ liệu, bất kỳ mã nào kẻ tấn công muốn sẽ chạy trên máy chủ của bạn

Chỉ cần sử dụng JSON

Đối với hầu hết các tác vụ phổ biến, chỉ cần sử dụng JSON để tuần tự hóa dữ liệu của bạn. Nó đủ nhanh, con người có thể đọc được, không gây ra các vấn đề về bảo mật và có thể được phân tích cú pháp bằng tất cả các ngôn ngữ lập trình đáng để biết. MessagePack cũng là một giải pháp thay thế tốt, tôi đã rất ngạc nhiên bởi nó hoạt động tốt như thế nào trong điểm chuẩn mà tôi đã tổng hợp

Mặt khác, Pickle chậm, không an toàn và chỉ có thể được phân tích cú pháp bằng Python. Ưu điểm thực sự duy nhất của pickle là nó có thể tuần tự hóa các đối tượng Python tùy ý, trong khi cả JSON và MessagePack đều có giới hạn về loại dữ liệu mà chúng có thể ghi ra. Mặc dù vậy, với những nhược điểm, bạn nên viết một đoạn mã nhỏ cần thiết để chuyển đổi các đối tượng của mình sang dạng có thể sử dụng JSON nếu mã của bạn sẽ được sử dụng bởi những người khác ngoài chính bạn

So sánh với hầu hết các ngôn ngữ lập trình phổ biến khác, Python có lẽ có khả năng tuần tự hóa các đối tượng linh hoạt nhất. Trong Python, mọi thứ đều là một đối tượng, vì vậy chúng ta có thể nói rằng hầu hết mọi thứ đều có thể được tuần tự hóa. Vâng, mô-đun mà tôi đang nói đến là Pickle

Tuy nhiên, so với các phương pháp tuần tự hóa “thông thường” khác như JSON, Pickle có nhiều khía cạnh cần cẩn thận hơn khi chúng ta sử dụng chúng. Đó là những gì tiêu đề đã nói, đừng sử dụng Pickle trừ khi bạn biết những sự thật này

Trong bài viết này, tôi sẽ sắp xếp một số lưu ý quan trọng về Pickle và hy vọng chúng sẽ giúp ích cho bạn.

1. Sử dụng cơ bản

Hình ảnh được cung cấp bởi Photo Mix từ Pixabay

Bằng cách sử dụng mô-đun Python Pickle, chúng ta có thể dễ dàng tuần tự hóa hầu hết các loại đối tượng vào một tệp. Trước khi chúng tôi có thể sử dụng nó, nó cần phải được nhập khẩu

import pickle

Hãy lấy từ điển làm ví dụ

my_dict = {
'name': 'Chris',
'age': 33
}

Chúng ta có thể sử dụng phương pháp

my_dict = {
'name': 'Chris',
'age': 33
}
7 để tuần tự hóa từ điển và ghi nó vào một tệp

with open['my_dict.pickle', 'wb'] as f:
pickle.dump[my_dict, f]

Sau đó, chúng ta có thể đọc tệp và tải nó trở lại một biến. Sau đó, chúng tôi có từ điển chính xác trở lại. Giống nhau 100% về nội dung

with open['my_dict.pickle', 'rb'] as f:
my_dict_unpickled = pickle.load[f]
my_dict == my_dict_unpickled

2. Tại sao dưa chua?

Hình ảnh được cung cấp bởi Christine Sponchia từ Pixabay

Thật vậy, sẽ có nhiều lợi ích hơn nếu chúng ta sử dụng JSON để tuần tự hóa một từ điển Python trong ví dụ trên. Nhìn chung có ba nhược điểm chính đối với việc xê-ri hóa Pickle

Nhược điểm-1. Dưa muối không an toàn

Không giống như JSON, chỉ là một đoạn chuỗi, 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

Do đó, chúng ta KHÔNG BAO GIỜ nên 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

Nhược điểm-2. Dưa chua không thể đọc được

Điều quan trọng nhất để tuần tự hóa từ điển Python thành chuỗi JSON là kết quả có thể đọc được bằng con người. Tuy nhiên, điều đó không đúng với tệp Pickle. Đây là tệp pickle cho từ điển mà chúng ta vừa chọn. Nếu chúng tôi cố mở nó dưới dạng tệp văn bản, đó là những gì chúng tôi sẽ nhận được

Nhược điểm-3. Pickle bị giới hạn trong Python

Một đối tượng dưa chua chỉ có thể được tải bằng Python. Các ngôn ngữ khác có thể được kích hoạt để làm như vậy nhưng yêu cầu phải có thư viện của bên thứ 3 và vẫn có thể không được hỗ trợ hoàn hảo

Ngược lại, một chuỗi JSON được sử dụng rất phổ biến trong thế giới lập trình và được hầu hết các ngôn ngữ lập trình hỗ trợ tốt

Ưu điểm của Pickle

Pickle xây dựng các đối tượng Python tùy ý bằng cách gọi các hàm tùy ý, đó là lý do tại sao nó không an toàn. Tuy nhiên, điều này cho phép nó tuần tự hóa hầu hết mọi đối tượng Python mà JSON và các phương thức tuần tự hóa khác sẽ không thực hiện được

Unpickling một đối tượng thường không yêu cầu "boilerplates". Vì vậy, nó rất phù hợp để lập số sê-ri nhanh chóng và dễ dàng. Ví dụ: bạn có thể kết xuất tất cả các biến vào tệp dưa chua và kết thúc chương trình của mình. Sau này, bạn có thể bắt đầu một phiên Python khác và khôi phục mọi thứ từ các tệp được tuần tự hóa. Vì vậy, điều này cho phép chúng tôi chạy một phần của chương trình theo cách linh hoạt hơn nhiều

Một ví dụ khác sẽ là đa luồng. Khi chúng tôi đang sử dụng mô-đun đa quy trình để chạy một chương trình trong nhiều luồng, chúng tôi có thể dễ dàng gửi các đối tượng Python tùy ý đến các quy trình khác hoặc các nút tính toán

Trong những trường hợp này, mối lo ngại về bảo mật thường không áp dụng và con người sẽ không phải đọc các đối tượng. Chúng tôi chỉ cần nhanh chóng, dễ dàng và tương thích. Trong những trường hợp này, Pickle có thể được sử dụng hoàn hảo

3. Những gì khác có thể được ngâm?

Chà, tôi tiếp tục nói về hầu hết mọi thứ có thể được xuất bản bởi Pickle. Bây giờ, hãy để tôi chỉ cho bạn một số ví dụ

Chọn một chức năng

Ví dụ đầu tiên sẽ là một chức năng. Có, chúng ta có thể tuần tự hóa một hàm trong Python, bởi vì một hàm cũng là một đối tượng trong Python

def my_func[num]:
print[f'my function will add 1 to the number {num}']
return num + 1

Chỉ cần xác định một chức năng đơn giản cho mục đích demo. Bây giờ, hãy chọn nó và tải nó vào một biến mới

with open['my_func.pickle', 'wb'] as f:
pickle.dump[my_func, f]
with open['my_func.pickle', 'rb'] as f:
my_func_unpickled = pickle.load[f]
my_func_unpickled[10]

Biến mới có thể được sử dụng như một hàm và hàm sẽ giống hệt với biến ban đầu

Pickle một khung dữ liệu Pandas

Một ví dụ khác sẽ là khung dữ liệu Pandas. Hãy xác định một khung dữ liệu Pandas

________số 8

Bây giờ, chúng ta có thể chọn nó và giải nén nó thành một biến mới. DataFrame mới sẽ giống hệt nhau

with open['my_df.pickle', 'wb'] as f:
pickle.dump[my_df, f]
with open['my_df.pickle', 'rb'] as f:
my_df_unpickled = pickle.load[f]

Xin lưu ý rằng Pandas có các phương thức tích hợp có thể chọn và giải nén khung dữ liệu. Họ sẽ làm công việc tương tự như trên, nhưng mã sẽ sạch hơn. Hiệu suất cũng giống hệt nhau

Sau đó, có thể có một câu hỏi, tại sao chúng ta nên sử dụng Pickle cho khung dữ liệu thay vì CSV?

Câu trả lời đầu tiên là tốc độ. CSV có thể đọc được bằng con người nhưng đây gần như là cách chậm nhất để lưu trữ khung dữ liệu Pandas

Bài đăng SO này đã đánh giá hiệu suất của các cách khác nhau để tuần tự hóa khung dữ liệu Pandas

Lợi ích thứ hai khi chọn khung dữ liệu Pandas là các loại dữ liệu. Khi chúng tôi ghi khung dữ liệu vào tệp CSV, mọi thứ phải được chuyển đổi thành văn bản. Đôi khi, điều này sẽ gây ra một số bất tiện hoặc rắc rối khi chúng tôi tải lại. Ví dụ: nếu chúng tôi ghi một cột ngày giờ vào CSV, chúng tôi có thể cần chỉ định chuỗi định dạng khi chúng tôi tải lại cột đó

Tuy nhiên, vấn đề này không tồn tại đối với một đối tượng dưa chua. Những gì bạn ngâm, bạn đảm bảo sẽ có lại chính xác thứ đó khi bạn tải nó. Không cần phải làm bất cứ điều gì khác

4. Phiên bản giao thức dưa chua

Hình ảnh được cung cấp bởi Anelka từ Pixabay

Việc sử dụng Pickle như những gì tôi đã làm trong các ví dụ trước là khá phổ biến. Họ không sai, nhưng sẽ thật tuyệt nếu chúng ta có thể chỉ định phiên bản giao thức của Pickle [thường là cao nhất]. Nói một cách đơn giản, sê-ri hóa Pickle có các phiên bản khác nhau. Khi các phiên bản Python đang lặp đi lặp lại, mô-đun Pickle cũng đang phát triển

Nếu bạn quan tâm các phiên bản hiện có là gì và những gì đã được cải thiện, đây là danh sách từ tài liệu chính thức

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 một cách hiệu quả hơn nhiều đối với các lớp kiểu mớ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 byte và không thể giải nén bằng Python 2. 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

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

Nói chung phiên bản cao hơn luôn tốt hơn phiên bản thấp hơn về mặt

  • Kích thước của các đối tượng ngâm
  • Hiệu suất của unpickling

Nếu chúng tôi chọn khung dữ liệu Pandas bằng các phiên bản khác nhau, chúng tôi có thể thấy sự khác biệt về kích thước

import pickle
0

Tại sao Python vẫn bảo lưu phiên bản cũ trong khi phiên bản mới luôn tốt hơn? . Điều đó có nghĩa là chúng ta phải chọn phiên bản thấp hơn nếu muốn tương thích tốt hơn

Tuy nhiên, nếu chúng ta đang sử dụng các đối tượng pickle mà không cần tương thích ngược, chúng ta có thể sử dụng phép liệt kê để đảm bảo chương trình của chúng ta sử dụng cái mới nhất [cái tốt nhất]. Ví dụ như sau

import pickle
15. Chọn một lớp tùy chỉnh

Hình ảnh được cung cấp bởi Shutterbug75 từ Pixabay

Mặc dù Pickle hỗ trợ hầu hết tất cả các đối tượng trong Python, nhưng chúng ta vẫn cần cẩn thận khi pickle một đối tượng được khởi tạo từ một lớp tùy chỉnh. Tóm lại, lớp cần tồn tại khi chúng ta tải lại đối tượng đã chọn

Ví dụ: hãy định nghĩa một lớp đơn giản “Người” với hai thuộc tính và một phương thức

my_dict = {
'name': 'Chris',
'age': 33
}
0

Bây giờ, hãy tuần tự hóa đối tượng “p” bằng Pickle

my_dict = {
'name': 'Chris',
'age': 33
}
1

Sự cố sẽ xảy ra nếu lớp không tồn tại. Điều này sẽ xảy ra nếu chúng tôi cố gắng tải đối tượng được chọn trong một phiên mới và lớp không được xác định. Chúng ta có thể mô phỏng kịch bản này bằng cách xóa định nghĩa lớp

my_dict = {
'name': 'Chris',
'age': 33
}
2

Sau đó, nếu chúng tôi cố gắng tải lại đối tượng đã ngâm, sẽ có một ngoại lệ

my_dict = {
'name': 'Chris',
'age': 33
}
3

Do đó, chúng ta cần đảm bảo rằng lớp đã tồn tại khi chúng ta tải lại đối tượng. Tuy nhiên, nếu định nghĩa của lớp hơi khác một chút, nó có thể không gây ra vấn đề nhưng hành vi của đối tượng có thể bị thay đổi dựa trên định nghĩa lớp mới

my_dict = {
'name': 'Chris',
'age': 33
}
4

Trong định nghĩa lớp mới, tôi đã sửa đổi thông báo in của phương pháp tự giới thiệu

Sau đó, nếu chúng ta tải lại đối tượng ngâm, sẽ không có bất kỳ lỗi nào, nhưng cách tự giới thiệu sẽ khác với ban đầu

my_dict = {
'name': 'Chris',
'age': 33
}
5

6. Không phải tất cả các đối tượng có thể được ngâm

Hình ảnh được cung cấp bởi Jenő Szabó từ Pixabay

Trong phần cuối cùng này, tôi phải quay lại tuyên bố ban đầu của mình “hầu như tất cả các đối tượng Python đều có thể được chọn”. Tôi sử dụng “gần như tất cả” vì vẫn còn một số loại đối tượng không thể được sắp xếp theo thứ tự bởi Pickle

Một loại điển hình không thể được chọn sẽ là các đối tượng kết nối trực tiếp, chẳng hạn như kết nối mạng hoặc cơ sở dữ liệu. Điều đó hợp lý vì Pickle sẽ không thể thiết lập kết nối sau khi đóng. Các đối tượng này chỉ có thể được tạo lại bằng thông tin đăng nhập phù hợp và các tài nguyên khác

Một loại khác cần được đề cập sẽ là một mô-đun. Một mô-đun quan trọng cũng không thể được ngâm. Xem ví dụ bên dưới

my_dict = {
'name': 'Chris',
'age': 33
}
6

Đây là điều quan trọng cần biết vì điều đó có nghĩa là chúng tôi sẽ không thể chọn mọi thứ trong

my_dict = {
'name': 'Chris',
'age': 33
}
8 vì mô-đun đã nhập sẽ ở trong đó

Tóm lược

Image by 旭刚 史 from Pixabay

Trong bài viết này, tôi đã giới thiệu phương thức tuần tự hóa tích hợp trong Python — Pickle. Nó có thể được sử dụng để lập số sê-ri nhanh chóng và dễ dàng. Nó hỗ trợ hầu hết tất cả các loại đối tượng Python như hàm và thậm chí cả khung dữ liệu Pandas. Khi sử dụng Pickle cho các phiên bản Python khác nhau, chúng ta cũng cần lưu ý rằng các phiên bản Pickle cũng có thể khác nhau

Tham gia Medium với liên kết giới thiệu của tôi - Christopher Tao

Là thành viên Phương tiện, một phần phí thành viên của bạn sẽ được chuyển đến các tác giả mà bạn đã đọc và bạn có toàn quyền truy cập vào mọi câu chuyện…

Trung bình. com

Nếu bạn cảm thấy bài viết của tôi hữu ích, hãy cân nhắc tham gia Medium Membership để ủng hộ tôi và hàng ngàn người viết khác. [Nhấp vào liên kết ở trên]

Dưa chua có nhỏ hơn JSON không?

Pickle dường như nhanh hơn khoảng 3 lần so với json và tạo ra tệp có kích thước bằng một nửa.

Dưa chua có tốt hơn JSON không?

Ngay cả các lớp và phương thức cũng có thể được tuần tự hóa với Pickle. JSON an toàn, trong khi Pickling không an toàn và dễ bị đe dọa bảo mật. Do đó, không nên giải nén dữ liệu từ các nguồn không xác định vì nó có thể chứa dữ liệu độc hại và sai sót

Python dưa muối có nhanh không?

Mặt khác, Pickle chậm, không an toàn và chỉ có thể được phân tích cú pháp bằng Python . Ưu điểm thực sự duy nhất của pickle là nó có thể tuần tự hóa các đối tượng Python tùy ý, trong khi cả JSON và MessagePack đều có giới hạn về loại dữ liệu mà chúng có thể ghi ra.

Dưa trăn có nén dữ liệu không?

Theo mặc định, định dạng dữ liệu dưa chua 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 đã chọn một cách hiệu quả .

Chủ Đề