无需文件,实现序列化 / 反序列化 Python 对象 情景: 有一些特殊的情景,需要两台机器通过 ssh 传输一些数据。
当然,通过文件传输 (sftp) 是最为方便的了。
但是不想有 io 怎么办呢?
我们需要用到两个 python build-in 的包:
base64 : 听名字就知道是干嘛的 pickle : 序列化 / 反序列化 Python 的一些基础对象如 dict, list 等 直接上代码: 服务端 (Server)
~/trans.py
trans.py
1 2 3 4 5 6 7 import base64 import pickle msg = ['message' , 'date' , 'author' , 'hash' ] base64.b64encode(pickle.dumps(msg)) print msg
客户端 (Client)
client.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import base64 import pickle import subprocess stdout, stderr = subprocess.Popen("ssh user@ip -c 'python trans.py'" , shell=True, stdout = subprocess.PIPE) ret = "" while True: line = sshout.readline() if line != '' : ret += line.rstrip('\n' ) else : break info = base64.b64decode(ret) msg = pickle.loads(info)
另外,客户端代码里面的这种方式,是能够实时从 buffer 里面读的。也就是说,远程输出一点内容,本地就能读到一点内容。
为何要这样做呢?这不是画蛇添足么? 你可能会问,为何要用 base64 来编码呢?其实只是因为 pickle 直接 dump 出来的字符串,如果直接 print 到 stdout,格式会非常难看,个人觉得会很容易出问题。比如你可以试试这样:
1 >>> print pickle.dumps({"我的" : "就是你的" })
其输出为:
1 2 3 4 5 6 (dp0 S'\xe6 \x 88 \x 91 \xe7 \x 9 a\x 84 ' p1 S'\xe5 \xb0 \xb1 \xe6 \x 98 \xaf\xe4 \xbd\xa0 \xe7 \x 9 a\x 84 ' p2 s.
来试试
1 2 3 4 5 6 7 8 9 10 >>> s = """(dp0 S'\xe6\x88\x91\xe7\x9a\x84' p1 S'\xe5\xb0\xb1\xe6\x98\xaf\xe4\xbd\xa0\xe7\x9a\x84' p2 s. """ >>> pickle.loads(s){'\xe6\x88\x91\xe7\x9a\x84' : '\xe5\xb0\xb1\xe6\x98\xaf\xe4\xbd\xa0\xe7\x9a\x84' }
当然,这里是可以被解析的,但是我并没有通过 ssh 来传输信息。
不同的 ssh wrap,可能对 stdout 的 buffer 处理不同。试想如果把这个信息 decode 或者 encode,或者替换掉非法字符,或者去掉换行符,那么我们就会很难受了。
如果用 base64 来编码一下呢?
1 2 >>> print(base64 .b64encode(pickle .dumps({"我的" : "就是你的" }))) KGRwMApTJ1x4ZTZceDg4XHg5MVx4ZTdceDlhXHg4NCcKcDEKUydceGU1XHhiMFx4YjFceGU2XHg5OFx4YWZceGU0XHhiZFx4YTBceGU3XHg5YVx4ODQnCnAyCnMu
多漂亮,不是吗?