Tuần tự hóa Python - Tại sao lại kén?


87

Tôi hiểu rằng chọn Python là một cách để 'lưu trữ' một Đối tượng Python theo cách tôn trọng lập trình Đối tượng - khác với đầu ra được viết bằng tệp txt hoặc DB.

Bạn có thêm thông tin chi tiết hoặc tham khảo các điểm sau:

  • vật ngâm được 'cất giữ' ở đâu?
  • tại sao pickling bảo quản biểu diễn đối tượng nhiều hơn là lưu trữ trong DB?
  • tôi có thể truy xuất các đối tượng đã chọn từ phiên shell Python này sang phiên khác không?
  • bạn có ví dụ quan trọng khi tuần tự hóa là hữu ích?
  • tuần tự hóa với dưa có ngụ ý dữ liệu 'nén'?

Nói cách khác, tôi đang tìm kiếm một tài liệu về quá trình ngâm - Python.doc giải thích cách triển khai dưa chua nhưng dường như không đi sâu vào chi tiết về việc sử dụng và sự cần thiết của tuần tự hóa.


Để lưu trạng thái để khôi phục sau này hoặc để chia sẻ / sao chép một đối tượng vào một thời gian chạy python khác sẽ là suy đoán của tôi.
synthesizerpatel

13
Nhiều câu hỏi của bạn được trả lời qua bài viết trên Wikipedia về tuần tự hóa: en.wikipedia.org/wiki/Serialization
NPE

5
bạn đang hỏi tại sao tôi cần Pickle để tuần tự hóa bằng Python? hay đúng hơn là (mục đích của) tuần tự hóa rốt cuộc là gì? .
moooeeeep

Có thể tốt khi đề cập đến các vấn đề bảo mật với dưa chua. Bạn có thể tìm thấy các ví dụ trong tài liệu và trong nhiều câu hỏi SO, như câu này .
djvg

Câu trả lời:


99

Pickling là một cách để chuyển đổi một đối tượng python (danh sách, dict, v.v.) thành một luồng ký tự. Ý tưởng là luồng ký tự này chứa tất cả thông tin cần thiết để tái tạo lại đối tượng trong một tập lệnh python khác.

Đối với nơi lưu trữ thông tin đã chọn, thông thường người ta sẽ làm:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Điều đó sẽ lưu trữ phiên bản rút gọn của vardict của chúng tôi trong tệp 'tên tệp'. Sau đó, trong một tập lệnh khác, bạn có thể tải từ tệp này vào một biến và từ điển sẽ được tạo lại:

with open('filename','rb') as f:
    var = pickle.load(f)

Một cách sử dụng khác để xử lý là nếu bạn cần truyền từ điển này qua mạng (có thể bằng ổ cắm hoặc thứ gì đó.) Trước tiên, bạn cần chuyển nó thành một luồng ký tự, sau đó bạn có thể gửi từ điển này qua kết nối ổ cắm.

Ngoài ra, không có "nén" để nói ở đây ... nó chỉ là một cách để chuyển đổi từ một biểu diễn (trong RAM) sang một biểu diễn khác (trong "văn bản").

About.com có ​​một bài giới thiệu hay về cách ngâm chua ở đây .


2
thường người ta sẽ làmwith open('filename') as f: ...
moooeeeep

3
Ngoài ra, bạn sẽ cần phải làm with open(filename, 'wb') as f: ...hoặc bạn sẽ không thể ghi vào tệp.
Tim Pietzcker

Cảm ơn!! Cái này về quản lý bền bỉ Python là tốt đẹp, đây
kiriloff

1
Nói chung, sử dụng pickleđể truyền từ điển qua mạng không phải là một ý kiến ​​hay (json có thể tốt hơn ở đây). Mặc dù trong một số trường hợp hiếm hoi, nó có thể hữu ích, ví dụ như multiprocessingmô-đun.
jfs

@Tim Pietzcker: protocol=0(mặc định trên Python2.x) có thể được sử dụng với các tệp được mở ở chế độ văn bản.
jfs

36

Pickling là hoàn toàn cần thiết cho tính toán phân tán và song song.

Giả sử bạn muốn thực hiện thu nhỏ bản đồ song song với multiprocessing(hoặc qua các nút cụm với pyina ), thì bạn cần đảm bảo rằng hàm bạn muốn ánh xạ trên các tài nguyên song song sẽ bị kén chọn. Nếu nó không kén, bạn không thể gửi nó đến các tài nguyên khác trên một quy trình khác, máy tính, v.v. Cũng có thể xem ví dụ điển hình ở đây .

Để làm điều này, tôi sử dụng thì là , có thể tuần tự hóa hầu hết mọi thứ trong python. Dill cũng có một số công cụ tốt để giúp bạn hiểu nguyên nhân khiến quá trình tẩy của bạn không thành công khi mã của bạn bị lỗi.

Và, vâng, mọi người sử dụng tính năng chọn để lưu trạng thái của một phép tính, hoặc phiên ipython của bạn , hoặc bất cứ điều gì. Bạn cũng có thể mở rộng Pickle's Pickler và UnPickler để thực hiện nén với bz2hoặc gzipnếu bạn muốn.


0

Tôi thấy nó đặc biệt hữu ích với các lớp tùy chỉnh lớn và phức tạp. Trong một ví dụ cụ thể mà tôi đang nghĩ đến, "Thu thập" thông tin (từ cơ sở dữ liệu) để tạo lớp đã là một nửa trận chiến. Sau đó, thông tin được lưu trữ trong lớp đó có thể bị người dùng thay đổi trong thời gian chạy.

Bạn có thể có một nhóm bảng khác trong cơ sở dữ liệu và viết một hàm khác để đi qua mọi thứ được lưu trữ và ghi nó vào các bảng cơ sở dữ liệu mới. Sau đó, bạn sẽ cần viết một hàm khác để có thể tải nội dung nào đó đã lưu bằng cách đọc lại tất cả thông tin đó.

Ngoài ra, bạn có thể chọn nguyên cả lớp và sau đó lưu trữ nó vào một trường duy nhất trong cơ sở dữ liệu. Sau đó, khi bạn tải lại, tất cả sẽ được tải trở lại cùng một lúc như trước đó. Điều này có thể giúp tiết kiệm rất nhiều thời gian và mã khi lưu và truy xuất các lớp phức tạp.


-1

nó là loại tuần tự hóa. sử dụng cPickle nó nhanh hơn nhiều so với dưa chua.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.