我有两个python脚本:object_generator.py,它们使给定的对象腌制并打印。另一个脚本object_consumer.py通过subprocess.communicate选择第一个脚本的输出,并尝试使用pickle.loads对其进行修补。我在使这个简单的方案起作用时遇到了麻烦。这是我的代码:
import pickle
import base64
o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}
d = pickle.dumps(o)
print(d)
#Various Approaches I had tried, none of which worked. Ignore this part.
#s = base64.b64decode(d)
#encoded_str = str(d).encode('ascii')
#print('encoded str is :')
#print(encoded_str)
#decoded_str = encoded_str.decode('ascii')
#print('decoded str is :')
#print(decoded_str)
#unpickled_obj = pickle.loads(bytes(decoded_str))
#print(unpickled_obj)
#print(type(d))
#print(codecs.decode(d))
import pickle
import subprocess
import os
dr = '"' + os.path.dirname(os.path.abspath(__file__)) + '\\object_generator.py"'
cmd = 'python -u ' + dr
proc = subprocess.Popen(cmd,stdout=subprocess.PIPE)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
# 'out' at this point is something like this :
# b"b'\\x80\\x03}q\......x05K\\x03u.'\r\n"
# DO SOMETHING WITH outs to get back the bytes which can then be
# unpickled using pickle.loads
obj = pickle.loads(outs)
print(obj)
显然,我需要删除尾随的\ r \ n,这很容易,但是接下来应该做什么?
这里有几个问题。首先,您要在中打印bytes
对象object_generator.py
。在Python 3.x中,这将导致str(obj)
被调用,即被b'yourbyteshere'
打印。您不希望开头b'
或结尾'
。要解决此问题,您需要将bytes
对象编码为字符串。pickle
使用'latin-1'
编码,因此我们可以使用该编码将bytes
对象解码为str
。另一个问题是Windows默认使用的编码sys.stdout
实际上并不支持打印解码的pickle
字符串。因此,我们需要将sys.stdout
*的默认编码更改为'latin-1'
,以便该字符串将使用正确的编码使其成为父进程。
import pickle
import base64
import codecs
o = {'first':1,'second':2,'third':3,'ls':[1,2,3]}
d = pickle.dumps(o)
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='latin-1')
print(d.decode('latin-1'), end='', flush=True) # end='' will remove that extra \r\n
进行那些更改,它应该可以正常工作。
编辑:
另一个选择是将PYTHONIOENCODING
环境变量设置为'latin-1'
来自父进程:
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'latin-1'
proc = subprocess.Popen(['python3', 'async2.py'] ,stdout=subprocess.PIPE, env=env)
*有关更改Python 3中的编码的更多信息,请参见此问题。sys.stdout
此处提到了我在此处显示的两种方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句