Làm thế nào tôi có thể sử dụng dưa chua để lưu một dict?


370

Tôi đã xem qua thông tin mà các tài liệu Python cung cấp, nhưng tôi vẫn hơi bối rối. Ai đó có thể đăng mã mẫu sẽ viết một tệp mới sau đó sử dụng dưa chua để đổ từ điển vào đó không?


5
Đọc qua điều này: doughellmann.com/PyMOTW/pickle và quay lại khi bạn cần một câu hỏi cụ thể
pyfunc

2
-1 Xem bình luận trước. Thử nó. Sau đó, nếu nó không hoạt động (nó sẽ không luôn luôn), một câu hỏi trực tiếp có thể được đặt ra (cùng với một hoặc hai giả thuyết có thể được kiểm tra và "truy vấn", có thể trước khi đặt câu hỏi cho người khác). Ví dụ, có một lỗi cú pháp? Một ngoại lệ? Có phải các giá trị trở lại bị cắt xén?

1
Tôi đã cố gắng sử dụng điều này để lưu thông tin từ pygame. Tôi đã sử dụng thông tin ở trên và mã của tôi trông như thế này:
Chachmu

name = raw_input ('tên tệp đầu vào:') tf = open (name + '. pkl', 'wb') pickle.dump (tổng, tf) tf.close ()
Chachmu

2
Bạn nên hỏi một câu hỏi mới về cách nhặt đồ vật trên bề mặt
John La Rooy

Câu trả lời:


727

Thử cái này:

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

print a == b

4
@houbysoft: Tại sao bạn lại gỡ bỏ pickle.HIGHEST_PROTOCOL?
Máy xay sinh tố

37
@Blender: không liên quan và phức tạp không cần thiết cho mức độ câu hỏi này - người dùng trung bình sẽ ổn với các mặc định.
houbysoft

28
@houbysoft: Đúng với người dùng Python 3, nhưng trên Python 2, sử dụng giao thức mặc định (0) không chỉ vô cùng kém hiệu quả về thời gian và không gian, mà thực tế nó không thể xử lý nhiều thứ mà giao thức 2+ xử lý tốt (ví dụ: mới các lớp học kiểu sử dụng __slots__). Tôi không nói rằng bạn nên luôn luôn sử dụng HIGHEST_PROTOCOL, nhưng đảm bảo bạn không sử dụng giao thức 0 hoặc 1 thực sự khá quan trọng.
ShadowRanger

11
Những gì pickle.HIGHEST_PROTOCOLthực sự làm?
BallpointBen

7
@BallpointBen: Nó chọn phiên bản giao thức cao nhất phiên bản của Python hỗ trợ: docs.python.org/3/library/pickle.html#data-stream-format
Máy xay sinh tố

92
import pickle

your_data = {'foo': 'bar'}

# Store data (serialize)
with open('filename.pickle', 'wb') as handle:
    pickle.dump(your_data, handle, protocol=pickle.HIGHEST_PROTOCOL)

# Load data (deserialize)
with open('filename.pickle', 'rb') as handle:
    unserialized_data = pickle.load(handle)

print(your_data == unserialized_data)

Ưu điểm HIGHEST_PROTOCOLlà các tập tin trở nên nhỏ hơn. Điều này làm cho việc tháo gỡ đôi khi nhanh hơn nhiều.

Thông báo quan trọng : Kích thước tệp tối đa của dưa chua là khoảng 2 GB.

Thay đổi phương pháp

import mpu
your_data = {'foo': 'bar'}
mpu.io.write('filename.pickle', data)
unserialized_data = mpu.io.read('filename.pickle')

Các định dạng thay thế

Đối với ứng dụng của bạn, những điều sau đây có thể quan trọng:

  • Hỗ trợ bởi các ngôn ngữ lập trình khác
  • Hiệu suất đọc / viết
  • Tính gọn nhẹ (kích thước tệp)

Xem thêm: So sánh các định dạng tuần tự hóa dữ liệu

Trong trường hợp bạn muốn tìm cách tạo tệp cấu hình, bạn có thể muốn đọc các tệp Cấu hình bài viết ngắn của tôi bằng Python


1
Tôi nghĩ rằng giới hạn 2GB đã bị xóa với giao thức = 4 và cao hơn.
ComputerSellectist

28
# Save a dictionary into a pickle file.
import pickle

favorite_color = {"lion": "yellow", "kitty": "red"}  # create a dictionary
pickle.dump(favorite_color, open("save.p", "wb"))  # save it into a file named save.p

# -------------------------------------------------------------
# Load the dictionary back from the pickle file.
import pickle

favorite_color = pickle.load(open("save.p", "rb"))
# favorite_color is now {"lion": "yellow", "kitty": "red"}

1
có cần thiết phải sử dụng close () sau open () không?
PlsWork

1
Vâng, nói chung. Tuy nhiên, trong CPython (Con trăn mặc định mà bạn có thể có), tệp sẽ tự động bị đóng bất cứ khi nào đối tượng tệp hết hạn (khi không có gì đề cập đến nó). Trong trường hợp này vì không có gì đề cập đến đối tượng tệp sau khi được open () trả về, nó sẽ bị đóng ngay khi tải trở lại. Đây không được coi là thông lệ tốt và sẽ gây ra sự cố trên các hệ thống khác
Ankur S

14

Nói chung, Pickling a dictsẽ thất bại trừ khi bạn chỉ có các đối tượng đơn giản trong đó, như chuỗi và số nguyên.

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import *
>>> type(globals())     
<type 'dict'>
>>> import pickle
>>> pik = pickle.dumps(globals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle module objects
>>> 

Ngay cả một thực sự đơn giản dictsẽ thường thất bại. Nó chỉ phụ thuộc vào nội dung.

>>> d = {'x': lambda x:x}
>>> pik = pickle.dumps(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <function <lambda> at 0x102178668>: it's not found as __main__.<lambda>

Tuy nhiên, nếu bạn sử dụng một bộ nối tiếp tốt hơn như dillhoặc cloudpickle, thì hầu hết các từ điển có thể được chọn:

>>> import dill
>>> pik = dill.dumps(d)

Hoặc nếu bạn muốn lưu dicttệp của bạn vào một tệp ...

>>> with open('save.pik', 'w') as f:
...   dill.dump(globals(), f)
... 

Ví dụ sau giống hệt với bất kỳ câu trả lời hay nào khác được đăng ở đây (ngoài việc bỏ qua khả năng chọn lọc nội dung của nội dung dictlà tốt).


9
>>> import pickle
>>> with open("/tmp/picklefile", "wb") as f:
...     pickle.dump({}, f)
... 

thông thường nên sử dụng triển khai cPickle

>>> import cPickle as pickle
>>> help(pickle.dump)
Help on built-in function dump in module cPickle:

dump(...)
    dump(obj, file, protocol=0) -- Write an object in pickle format to the given file.

    See the Pickler docstring for the meaning of optional argument proto.

6

Nếu bạn chỉ muốn lưu trữ dict trong một tệp duy nhất, hãy sử dụng picklenhư thế

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

Nếu bạn muốn lưu và khôi phục nhiều từ điển trong nhiều tệp để lưu trữ và lưu trữ dữ liệu phức tạp hơn, hãy sử dụng anycache . Nó làm tất cả những thứ khác bạn cần xung quanhpickle

from anycache import anycache

@anycache(cachedir='path/to/files')
def myfunc(hello):
    return {'hello', hello}

Anycache lưu trữ các myfunckết quả khác nhau tùy thuộc vào các đối số cho các tệp khác nhau cachedirvà tải lại chúng.

Xem tài liệu để biết thêm chi tiết.


6

Cách đơn giản để kết xuất dữ liệu Python (ví dụ: từ điển) vào tệp dưa chua.

import pickle

your_dictionary = {}

pickle.dump(your_dictionary, open('pickle_file_name.p', 'wb'))

3
import pickle

dictobj = {'Jack' : 123, 'John' : 456}

filename = "/foldername/filestore"

fileobj = open(filename, 'wb')

pickle.dump(dictobj, fileobj)

fileobj.close()

-8

Tôi đã tìm thấy dưa chua khó hiểu (có thể vì tôi dày). Tôi thấy rằng điều này hoạt động, mặc dù:

myDictionaryString=str(myDictionary)

Mà sau đó bạn có thể viết vào một tệp văn bản. Tôi đã từ bỏ việc cố gắng sử dụng dưa chua vì tôi gặp lỗi khi bảo tôi viết số nguyên vào tệp .dat. Tôi xin lỗi vì đã không sử dụng dưa chua.


1
-1: Nên lưu nó như hiện tại (tức là một đối tượng python) để chúng ta có thể đọc nó sau mà không cần chờ đợi để chạy lại nó. Pickle cho phép chúng ta lưu trữ một đối tượng python để đọc sau.
Catbuilts

Đây là một câu trả lời cũ quay trở lại trong hàng Bài viết chất lượng thấp .. Nó không phải là một giải pháp tồi ở chỗ nó có thể hoạt động cho các từ điển rất đơn giản, nhưng nó rất hợp lý dictđể chứa các đối tượng có chiều sâu hơn (có thể được in chỉ bằng tên) và / hoặc các đối tượng mà không có bất kỳ hoặc một đại diện chuỗi hoàn chỉnh.
ti7

1
Để thêm vào điểm của @ ti7, bất kể giá trị kỹ thuật của câu trả lời, bài đăng này không phải là VLQ. Nếu ai đó cảm thấy rằng câu trả lời này không chính xác, họ nên downvote và / hoặc bình luận giải thích lý do tại sao, không gắn cờ nó là VLQ.
EJoshuaS - Phục hồi Monica
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.