Tôi có thể sử dụng cái gì thay vì dưa chua trong Python?

Khi một chương trình đang chạy, tất cả các đối tượng Python được lưu trữ tạm thời trong bộ nhớ hệ thống và khi chương trình kết thúc, tất cả bộ nhớ bị chiếm dụng sẽ được hệ điều hành thu hồi. Đây là một câu hỏi. Làm cách nào chúng ta có thể lưu trữ các đối tượng Python trong đĩa hoặc gửi chúng qua mạng?

Trong Python, bạn có thể sử dụng pickle để tuần tự hóa [giải tuần tự hóa] một cấu trúc đối tượng thành [từ] một luồng byte. Dưới đây là các phương pháp hay nhất để tẩy Python an toàn

Bởi Ashutosh Agrawal, cố vấn cao cấp, và Arvind Balaji, cố vấn liên kết, Synopsys

Pickle trong Python chủ yếu được sử dụng trong tuần tự hóa và giải tuần tự hóa cấu trúc đối tượng Python. Nói cách khác, đó là quá trình chuyển đổi một đối tượng Python thành luồng byte để lưu trữ nó trong tệp/cơ sở dữ liệu, duy trì trạng thái chương trình qua các phiên hoặc truyền dữ liệu qua mạng. Luồng byte được chọn có thể được sử dụng để tạo lại hệ thống phân cấp đối tượng ban đầu bằng cách bỏ chọn luồng. Toàn bộ quá trình này tương tự như tuần tự hóa đối tượng trong Java hoặc. Bọc lưới

Khi một luồng byte không được chọn, trước tiên mô-đun pickle sẽ tạo một phiên bản của đối tượng ban đầu và sau đó điền vào phiên bản đó bằng dữ liệu chính xác. Để đạt được điều này, luồng byte chỉ chứa dữ liệu dành riêng cho thể hiện đối tượng ban đầu. Nhưng chỉ có dữ liệu thôi có thể không đủ. Để giải nén thành công đối tượng, luồng byte đã chọn chứa các hướng dẫn cho trình giải mã để tái tạo lại cấu trúc đối tượng ban đầu cùng với các toán hạng lệnh, giúp điền vào cấu trúc đối tượng

Theo tài liệu mô-đun dưa chua, các loại sau có thể được ngâm

  • Không, đúng và sai
  • Số nguyên, số nguyên dài, số dấu phẩy động, số phức
  • Chuỗi bình thường và Unicode
  • Bộ dữ liệu, danh sách, bộ và từ điển chỉ chứa các đối tượng có thể chọn
  • Các chức năng được xác định ở cấp cao nhất của mô-đun
  • Các chức năng tích hợp được xác định ở cấp cao nhất của mô-đun
  • Các lớp được định nghĩa ở cấp cao nhất của mô-đun

Pickle cho phép các đối tượng khác nhau khai báo cách chúng nên được ngâm bằng phương thức __reduce__. Bất cứ khi nào một đối tượng được chọn, phương thức __reduce__ được xác định bởi nó sẽ được gọi. Phương thức này trả về một chuỗi, có thể đại diện cho tên của toàn cục Python hoặc một bộ mô tả cách tái tạo lại đối tượng này khi giải nén

Nói chung, tuple bao gồm hai đối số

  • Có thể gọi được [trong hầu hết các trường hợp sẽ là tên của lớp cần gọi]
  • Các đối số được chuyển đến có thể gọi ở trên

Thư viện pickle sẽ chọn riêng từng thành phần của bộ dữ liệu và sẽ gọi đối tượng có thể gọi được trên các đối số được cung cấp để xây dựng đối tượng mới trong quá trình giải nén

Nguy hiểm khi ngâm trăn

Vì không có cách hiệu quả nào để xác minh luồng dưa chua được giải nén, nên có thể cung cấp mã shell độc hại làm đầu vào, gây ra việc thực thi mã từ xa. Kịch bản tấn công phổ biến nhất dẫn đến điều này là tin tưởng vào dữ liệu pickle thô nhận được qua mạng. Nếu kết nối không được mã hóa, dưa nhận được cũng có thể đã được sửa đổi trên dây. Một kịch bản tấn công khác là khi kẻ tấn công có thể truy cập và sửa đổi các tệp pickle được lưu trữ từ bộ đệm, hệ thống tệp hoặc cơ sở dữ liệu

Mã ví dụ sau thể hiện chữ ký và xác minh mật mã. Chữ ký mật mã, như đã đề cập ở trên, giúp phát hiện bất kỳ sự thay đổi nào của dữ liệu đã chọn. Khách hàng sử dụng HMAC để ký dữ liệu. Nó gửi giá trị thông báo cùng với dữ liệu được chọn đến máy chủ như hình bên dưới

Nếu bạn muốn lưu trữ [chọn] các đối tượng python vào một tệp pickle duy nhất mà không đi kèm với các mô-đun có định nghĩa lớp/hàm, bạn nên

  1. Sử dụng
    greeter = Greeter[[greeting1, greeting2]]
    greeter.greet[]
    
    9 thay vì
    Booyaa!
    Howdy!
    
    0
  2. Sử dụng một số thủ thuật để lừa
    greeter = Greeter[[greeting1, greeting2]]
    greeter.greet[]
    
    9 tin rằng việc nhập khẩu đã thực sự được xác định trong
    Booyaa!
    Howdy!
    
    2

Dưa chua với sự phụ thuộc

Khi bạn muốn chọn một đối tượng python để lưu trữ lâu dài, bạn có thể gặp sự cố. dưa chua không lưu trữ định nghĩa đối tượng khi dưa chua. Vì vậy, ví dụ: khi bạn xây dựng một

Booyaa!
Howdy!
3, sau đó chọn và bỏ chọn nó ở một vị trí khác, bạn cần phải xác định chính xác
Booyaa!
Howdy!
3 trước khi có thể tải pickle tại đích đích

def greeting1[]:
    return "Booyaa!"

def greeting2[]:
    return "Howdy!"

class Greeter:
    def __init__[self, greetings]:
        self.greetings = greetings
        
    def greet[self]:
        for greet in self.greetings:
            print[greet[]]

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]

Booyaa!
Howdy!

import pickle 

pickle.dump[greeter, open["greeter.pkl", "wb"]]

Nếu bây giờ bạn thử tải lời chào ở một nơi khác, bạn sẽ nhận được một

Booyaa!
Howdy!
5

Booyaa!
Howdy!
1

Giải pháp 1. Cũng lưu trữ mô-đun với các định nghĩa

Một cách giải quyết vấn đề này bằng cách lưu trữ định nghĩa lớp của

Booyaa!
Howdy!
6 trong
Booyaa!
Howdy!
7, nhập
Booyaa!
Howdy!
6 từ
Booyaa!
Howdy!
9 và sao chép
Booyaa!
Howdy!
7 cùng với
import pickle 

pickle.dump[greeter, open["greeter.pkl", "wb"]]
1 vào vị trí bạn muốn bỏ chọn

Tuy nhiên, bây giờ bạn đã tạo một phụ thuộc mà bạn cần quản lý. Bạn luôn phải đảm bảo rằng bạn có sẵn phiên bản phù hợp của mô-đun phù hợp khi bạn muốn mở khóa. Đặc biệt đối với việc lưu trữ lâu dài các đối tượng python, điều này đang gây ra sự cố. Sẽ tốt hơn nếu bạn có thể có tất cả đối tượng và định nghĩa trong một tệp

Giải pháp 2. Dill để giải cứu

May mắn thay, có một sự thay thế độc lập cho

Booyaa!
Howdy!
0 được gọi là
greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
9, tiếc là không đi kèm với thư viện tiêu chuẩn, vì vậy bạn phải tự cài đặt nó.
import pickle 

pickle.dump[greeter, open["greeter.pkl", "wb"]]
4

Điều thú vị về

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
9 là nó lưu trữ các định nghĩa cùng với đối tượng, miễn là chúng được định nghĩa trong
Booyaa!
Howdy!
2. Trong trường hợp của chúng tôi, chúng là như vậy khi chúng tôi lưu trữ đối tượng lời chào với dill, chúng tôi thực sự có thể tải lại đối tượng ngay bây giờ

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
3

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
4

Nó đã làm việc

Nhưng chỉ lưu trữ các định nghĩa trong
Booyaa!
Howdy!
2 chứ không phải trong các mô-đun

Giả sử chúng ta định nghĩa

Booyaa!
Howdy!
6 trong mô-đun
import pickle 

pickle.dump[greeter, open["greeter.pkl", "wb"]]
9

người chào hỏi. py

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
8

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
9

Sau đó, dưa chua lại không tải được khi

Booyaa!
Howdy!
7 bị thiếu hoặc bỏ lỡ các định nghĩa đúng

Booyaa!
Howdy!
1

cách giải quyết. di chuyển các định nghĩa sang
Booyaa!
Howdy!
2

Bạn có thể giải quyết vấn đề này bằng cách

Booyaa!
Howdy!
12 các định nghĩa đã nhập

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
0

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
1

Và điều này hoạt động

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
2

Tránh sử dụng
Booyaa!
Howdy!
13 trong
Booyaa!
Howdy!
2

Tuy nhiên, nó hơi cồng kềnh để

Booyaa!
Howdy!
13 mọi thứ và bạn có thể muốn tự động hóa việc này cho người dùng của mình

Một cách để làm điều này là khai báo một classmethod

Booyaa!
Howdy!
16

sử dụng
Booyaa!
Howdy!
17

chào mừng2. py

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
3

Bây giờ bạn có thể nhập chính

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
4

Booyaa!
Howdy!

sử dụng
Booyaa!
Howdy!
18

người chào3. py

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
6

greeter = Greeter[[greeting1, greeting2]]
greeter.greet[]
7

Booyaa!
Howdy!

Phần kết luận

Hy vọng điều này có thể hữu ích cho một số bạn muốn lưu trữ các đối tượng python và không lo lắng về các phụ thuộc mô-đun

Cái gì nhanh hơn dưa Python?

quickle là định dạng tuần tự hóa nhỏ và nhanh cho một tập hợp con các loại Python. Nó dựa trên Pickle, nhưng bao gồm một số tối ưu hóa và tiện ích mở rộng để cung cấp hiệu suất và bảo mật được cải thiện. Đối với các loại được hỗ trợ, sắp xếp theo thứ tự một tin nhắn bằng quickle có thể nhanh hơn ~2-10 lần so với sử dụng pickle.

Tôi có nên sử dụng dưa chua hoặc JSON Python không?

JSON là định dạng nhẹ và nhanh hơn nhiều so với Pickling . Luôn có rủi ro bảo mật với Pickle. Nên tránh 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 hoặc sai sót. Không có lỗ hổng bảo mật nào khi sử dụng JSON và không có mối đe dọa bảo mật nào.

Tại sao không sử dụng dưa chua Python?

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

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

Đó là tốc độ tăng khoảng 80 lần, nếu bạn không quan tâm đến việc nén. Pickle lần này nhanh hơn khoảng 11 lần, khi không nén. Quá trình nén là một vấn đề lớn khi đọc và lưu tệp. Nhưng, hãy xem nó tiết kiệm được bao nhiêu dung lượng đĩa

Chủ Đề