[英]Pickle cross platform __dict__ attribute error
我泡菜有問題。 OSX和Linux之間可以正常工作,但Windows和Linux不能正常工作。 所有腌制的字符串都存儲在內存中,並通過SSL套接字發送。 為了100%清楚,我將所有'\\ n替換為“ :::”,並將所有'\\ r替換為“ ===”(沒有)。 場景:
客戶端林將一個腌制的對象發送到服務器:
ccopy_reg:::_reconstructor:::p0:::(c__main__:::infoCollection:::p1:::c__builtin__:::tuple:::p2:::(VSTRINGA:::p3:::VSTRINGB:::p4:::VSTRINGC:::p5:::tp6:::tp7:::Rp8:::.
Client-Win將選擇的對象發送到服務器:
ccopy_reg:::_reconstructor:::p0:::(c__main__:::infoCollection:::p1:::c__builtin__:::tuple:::p2:::(VSTRINGA:::p3:::VSTRINGB:::p4:::VSTRINGC:::p5:::tp6:::tp7:::Rp8:::ccollections:::OrderedDict:::p9:::((lp10:::(lp11:::S'string_a':::p12:::ag3:::aa(lp13:::S'string_b':::p14:::ag4:::aa(lp15:::S'string_c':::p16:::ag5:::aatp17:::Rp18:::b.
出於某種原因,Windows客戶端會與泡菜一起發送額外的信息,而當Linux客戶端嘗試加載泡菜字符串時,我會得到:
Unhandled exception in thread started by <function TestThread at 0x107de60>
Traceback (most recent call last):
File "./test.py", line 212, in TestThread
info = pickle.loads(p_string)
File "/usr/lib64/python2.7/pickle.py", line 1382, in loads
return Unpickler(file).load()
File "/usr/lib64/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/usr/lib64/python2.7/pickle.py", line 1224, in load_build
d = inst.__dict__
AttributeError: 'infoCollection' object has no attribute '__dict__'
有任何想法嗎?
編輯添加其他要求的信息。
infoCollection類的定義方式相同:
infoCollection = collections.namedtuple('infoCollection', 'string_a, string_b, string_c')
def runtest():
info = infoCollection('STRINGA', 'STRINGB', 'STRINGC')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
ssl_sock.connect((server, serverport))
ssl_sock.write(pickle.dumps(info))
ssl_sock.close()
接收功能大致相同,但是
p_string = ssl_sock.read()
info = pickle.loads(p_string)
您是否正在使用其他次要版本的Python? 2.7.3中存在一個錯誤,該錯誤使酸洗namedtuple與舊版本不兼容。 看到這個:
http://ronrothman.com/public/leftbraned/python-2-7-3-bug-broke-my-namedtuple-unpickling/
駭客入侵,但跨平台問題似乎是由於跨平台環境中的namedtuple和pickle共同造成的。 我已經用我自己的類替換了namedtuple,並且一切正常。
class infoClass(object):
pass
def infoCollection(string_a, string_b, string_c):
i = infoClass()
i.string_a = string_a
i.string_b = string_b
i.string_c = string_c
return i
您是否嘗試過將其保存為二進制泡菜文件?
with open('pickle.file', 'wb') as po:
pickle.dump(obj, po)
另外-如果要在各種操作系統之間進行移植,並且info
只是一個namedtuple
,您是否看過JSON (通常認為它比pickle
安全)?
with open('pickle.json', 'w') as po:
json.dump(obj, po)
編輯從ssl
.read()
文檔看來,默認情況下.read()
最多只能讀取1024個字節,我敢打賭,您的info
namedtuple將會更大。 我不知道先驗的大info
是很難的,我不知道僅僅設置nbytes=HUGE NUMBER
是否可以解決問題(我想也許不行)。
如果你會發生什么
p_string = ssl_sock.read(nbytes=1.0E6)
info = pickle.loads(p_string)
只需從https://www.python.org/ftp/python/2.7.8/python-2.7.8.amd64.msi安裝Pyhton 2.7.8
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.