2009-03-30 34 views
9

Mô-đun dưa có vẻ sử dụng các ký tự thoát chuỗi khi tẩy; điều này trở nên không hiệu quả, ví dụ: trên mảng numpy. Hãy xem xét những điều sau đâycách hiệu quả hơn để chọn một chuỗi

z = numpy.zeros(1000, numpy.uint8) 
len(z.dumps()) 
len(cPickle.dumps(z.dumps())) 

Độ dài là 1133 ký tự và 4249 ký tự tương ứng.

z.dumps() cho thấy một cái gì đó như "\ x00 \ x00" (số không thực tế trong chuỗi), nhưng dưa có vẻ là sử dụng hàm repr() của chuỗi, cho ra "'\ x00 \ x00'" (số không ascii số không).

tức ("0" trong z.dumps() == False) và ("0" trong cPickle.dumps (z.dumps()) == True)

+0

Bạn nên thêm câu hỏi cụ thể vào bài đăng của mình lại. –

+0

Bạn muốn tuần tự hóa một chuỗi Python hoặc một mảng byte có nhiều mảng? – jfs

+1

nên được len (cPickle.dumps (z)) – vartec

Trả lời

23

Hãy thử sử dụng một phiên bản sau của giao thức dưa với tham số giao thức là pickle.dumps(). Giá trị mặc định là 0 và là định dạng văn bản ASCII. Những người lớn hơn 1 (tôi đề nghị bạn sử dụng pickle.HIGHEST_PROTOCOL). Các định dạng giao thức 1 và 2 (và 3 nhưng đó là cho py3k) là nhị phân và nên có nhiều không gian bảo thủ hơn.

+0

[Python 3 sử dụng giao thức 3 theo mặc định.] (Https://docs.python.org/3/library/pickle.html#data-stream-format) –

8

Giải pháp:

import zlib, cPickle 

def zdumps(obj): 
    return zlib.compress(cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL),9) 

def zloads(zstr): 
    return cPickle.loads(zlib.decompress(zstr)) 

>>> len(zdumps(z)) 
128 
+0

Đây là một cái gì đó nhiều hơn về chủ đề: http://tinyurl.com/3ymhaj5. Về cơ bản, nếu bạn đang serializing vào đĩa bạn chỉ có thể làm gzip.open() thay vì mở. –

+0

@ slack3r liên kết đã chết. – kynan

+0

'ascii' codec không thể mã hóa ký tự u '\ xda' ở vị trí 1: thứ tự không nằm trong phạm vi (128) –

1

Một cải tiến để đáp vartec, đó có vẻ hơi nhiều bộ nhớ hiệu quả (vì nó không buộc tất cả mọi thứ vào một string):

def pickle(fname, obj): 
    import cPickle, gzip 
    cPickle.dump(obj=obj, file=gzip.open(fname, "wb", compresslevel=3), protocol=2) 

def unpickle(fname): 
    import cPickle, gzip 
    return cPickle.load(gzip.open(fname, "rb")) 
+0

-1 (1) Không mã số giao thức mã cứng, sử dụng '-1' hoặc' HIGHEST_PROTOCOL' . (2) Nén tiếp theo là một ADD-ON và không liên quan đến câu hỏi của anh ta. (3) Chỉ định 'compresslevel' khi giải nén là vô nghĩa; bất kỳ thông tin nào có thể cần thiết để giải nén tệp sẽ được lưu trữ trong tiêu đề của tệp nén - nếu không bạn sẽ có thể giải nén tệp nếu bạn không biết mức độ nén được sử dụng là gì? –

+0

(1) Sau đó mã py2 sẽ không đọc các đối tượng py3. (2) tiêu đề cho biết "một cải tiến cho câu trả lời của vartec", sử dụng nén - Tôi nghĩ nó sử dụng ít mem hơn, nhưng nó có thể là một ấn tượng sai lầm ... (3) cố định – gatoatigrado

3

z.dumps() đã được ngâm chuỗi tức là, nó có thể được bỏ chọn bằng cách sử dụng pickle.loads():

>>> z = numpy.zeros(1000, numpy.uint8) 
>>> s = z.dumps() 
>>> a = pickle.loads(s) 
>>> all(a == z) 
True 
Các vấn đề liên quan