4

我有泡菜的问题。在 OSX 和 Linux 之间运行良好,但在 Windows 和 Linux 之间运行良好。所有腌制字符串都存储在内存中并通过 SSL 套接字发送。为了 100% 清楚,我已将所有 '\n's 替换为 ":::" 并将所有 '\r's 替换为 "==="(没有)。设想:

  • Client-Win:运行 Python 2.7 的 Small Business Server 2011
  • Client-Lin:运行 Python 2.7 的 Fedora Linux
  • 服务器:运行 Python 2.7 的 Fedora Linux

Client-Lin 向服务器发送一个腌制对象:

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 客户端会与 pickle 一起发送额外的信息,当 Linux 客户端尝试加载 pickle 字符串时,我会得到:

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)
4

5 回答 5

3

您是否使用不同的 Python 次要版本?2.7.3 中有一个错误导致酸洗命名元组与旧版本不兼容。看到这个:

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

于 2013-03-30T15:48:59.437 回答
2

一个hack,但跨平台问题似乎是由于跨平台环境中的namedtuples和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
于 2013-02-19T14:53:33.640 回答
0

您是否尝试过保存为二进制泡菜文件?

with open('pickle.file', 'wb') as po:
    pickle.dump(obj, po)

另外-如果您要在各种操作系统之间进行移植,并且infonamedtuple是否看过JSON(通常认为它比 更安全pickle)?

with open('pickle.json', 'w') as po:
    json.dump(obj, po)

编辑ssl .read() 文档看来,.read()默认情况下最多只能读取 1024 个字节,我敢打赌你的infonamedtuple 会比这更大。很难知道先验有info多大,我不知道设置是否可以解决问题(我认为可能不会)。nbytes=HUGE NUMBER

于 2013-02-19T14:35:40.537 回答
0

如果你会发生什么

p_string = ssl_sock.read(nbytes=1.0E6)
info = pickle.loads(p_string)
于 2013-02-19T15:04:49.537 回答
0

只需从https://www.python.org/ftp/python/2.7.8/python-2.7.8.amd64.msi安装 Pyhton 2.7.8

于 2015-03-10T13:41:59.287 回答