Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过subprocess.communicate在python脚本之间传输pickle对象输出_Python_Python 3.x_Pickle - Fatal编程技术网

通过subprocess.communicate在python脚本之间传输pickle对象输出

通过subprocess.communicate在python脚本之间传输pickle对象输出,python,python-3.x,pickle,Python,Python 3.x,Pickle,我有两个python脚本:object_generator.py,它pickle一个给定的对象并打印它。另一个脚本对象_consumer.py通过subprocess.communicate拾取第一个脚本的输出,并尝试使用pickle.loads解除对其的pickle。我很难让这个简单的场景工作。这是我的代码: object_generator.py object_consumer.py 显然,我需要去掉尾随\r\n,这很容易,但接下来应该做什么?这里有几个问题。首先,在object\u gen

我有两个python脚本:object_generator.py,它pickle一个给定的对象并打印它。另一个脚本对象_consumer.py通过subprocess.communicate拾取第一个脚本的输出,并尝试使用pickle.loads解除对其的pickle。我很难让这个简单的场景工作。这是我的代码:

object_generator.py object_consumer.py
显然,我需要去掉尾随\r\n,这很容易,但接下来应该做什么?

这里有几个问题。首先,在
object\u generator.py
中打印一个
bytes
对象。在Python3.x中,这将导致调用
str(obj)
,这意味着打印
b'yourbyteshere'
。您不需要前导的
b'
或尾随的
'
。要解决这个问题,需要将
字节
对象编码为字符串
pickle
使用
'latin-1'
编码,因此我们可以使用它将
字节
对象解码为
str
。另一个问题是,默认情况下,编码窗口用于
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
做出这些改变,它应该可以正常工作

编辑:

另一个选项是从父进程将
pythonionecoding
环境变量设置为
'latin-1'

env = os.environ.copy()
env['PYTHONIOENCODING'] = 'latin-1'
proc = subprocess.Popen(['python3', 'async2.py'] ,stdout=subprocess.PIPE, env=env)

*有关在Python3中更改
sys.stdout
编码的更多信息,请参阅。这里提到的两种方法。

我不建议您在主文件和未知外部文件之间使用pickle,因为它要求原始类处于活动状态,而且速度也很慢


我使用了marshall模块,希望这能节省您的时间:

您的工作目标是使用给定的
子流程
模块方法
.communicate()
,还是实现python进程到进程的通信解决方案,是使用
子流程
还是其他方式?我尝试了子流程。检查输出,然后在不起作用时移动到通信,但我没有使用通信的限制。我希望您能提供任何替代方法,并解释其中的错误。最好将进程间通信问题与有效负载表示/编码/序列化/封装/成帧问题分开。对于前者,可能有助于了解快速、可扩展的进程到进程消息传递ZeroMQ(具有许多端口,包括python)的概况,在ZeroMQ中,您可以获得自己控制下的所有功能,从而能够将通信原型适配到分布式并行处理项目的需要中。我看到你收回了你的答案并重新发布了修复。感谢您的耐心和付出的努力。@rusticbit是的,我最初的答案在Linux上运行良好,但在Windows上不起作用。我忘记了Windows上使用的默认编码
sys.stdout
的区别。@rusticbit我更新了答案,使用
io
模块,而不是
codecs
,因为
io
模块。我还添加了一种从父脚本解决问题的方法。
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
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'latin-1'
proc = subprocess.Popen(['python3', 'async2.py'] ,stdout=subprocess.PIPE, env=env)