2013-02-19 16 views
4

我遇到了泡菜問題。 OSX和Linux之間的事情很好,但不是Windows和Linux。所有醃製的字符串都存儲在內存中,並通過SSL套接字發送。爲了100%清楚,我用「:::」替換了所有的\ n,並用「===」替換了所有的\ r。(沒有)。場景:Python泡菜scross平臺__dict__屬性錯誤

  • 客戶贏:的Small Business Server 2011上運行的Python 2.7
  • 客戶林:Fedora Linux系統上運行的Python 2.7
  • 服務器:Fedora的Linux上運行的Python 2.7

客戶端林發送一個酸洗對象到服務器:

ccopy_reg:::_reconstructor:::p0:::(c__main__:::infoCollection:::p1:::c__builtin__:::tuple:::p2:::(VSTRINGA:::p3:::VSTRINGB:::p4:::VSTRINGC:::p5:::tp6:::tp7:::Rp8:::.

客戶贏發送挑對象服務器:

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) 
+0

也許安裝Pyhton 2.7.8你能告訴我們,做酸洗的代碼,並進入它的數據? – Evert 2013-02-19 14:14:28

+0

在兩種環境中,類「infoCollection」的定義是否完全相同? – mgilson 2013-02-19 14:18:49

+0

剛剛更新了帖子,提供了更多信息。 – Fmstrat 2013-02-19 14:36:39

回答

2

駭客,但跨平臺問題似乎是由於在跨平臺環境中將namedtuples和pickle結合在一起。我已經用自己的班級取代了這個名字,並且一切正常。

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 
+0

如果有人解決了named/pickle組合錯誤。我會很高興地將此標記爲更正式的答案。 – Fmstrat 2013-02-19 14:54:07

+0

問題是重構功能,我想。我寧願你的解決方案來修復別人的代碼。 – User 2013-02-19 15:30:52

0

你試過另存爲二進制文件泡菜?

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()docs似乎.read()將只讀取默認最多1024個字節,我敢打賭,你的info namedtuple將是比大。這將是很難知道有多大info先驗我不知道是否設置nbytes=HUGE NUMBER會做的伎倆(我想也許不是)。

+0

我曾想過JSON,但JSON並不提供過渡對象的簡易性。 I.E.用pickle我可以訪問「info.STRINGA」,而不必在每次加載字符串時重新定義事物。另外,我不能輕鬆使用pickle binary,因爲我通過套接字從內存發送。 – Fmstrat 2013-02-19 14:42:44

0

如果你

p_string = ssl_sock.read(nbytes=1.0E6) 
info = pickle.loads(p_string) 
3

你使用Python的不同次要版本會發生什麼? 2.7.3中存在一個缺陷,使酸洗命名區域與舊版本不兼容。看到這一點:

http://ronrothman.com/public/leftbraned/python-2-7-3-bug-broke-my-namedtuple-unpickling/

+0

歡迎!爲了將來參考,請在要求澄清的問題下留言。然後在你有需要的信息時回答。 – FakeRainBrigand 2013-03-30 16:12:15

+1

謝謝。也許我應該以不同的方式回答答案?可能是這樣的:「這個問題通常是由...引起的?」? – jjw 2013-03-30 17:40:28