代码之家  ›  专栏  ›  技术社区  ›  Geo

您只能与子流程通信一次吗?

  •  4
  • Geo  · 技术社区  · 15 年前

    communicate 文件上说:

    与进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到到达文件结尾。等待进程终止。

    如果您需要将输入多次发送到一个进程,您会怎么做?例如,我生成一个进程,向它发送一些数据,该进程用它做一些事情,返回一些输出,然后我必须再次发送输入?我该怎么处理?

    4 回复  |  直到 10 年前
        1
  •  2
  •   Nick Craig-Wood    15 年前

    不要使用 subprocess 为此,你将进入一个痛苦的世界来缓冲。

    我推荐 pexpect 为此目的-它工作得很好。不幸的是,目前它在Windows下不起作用,尽管我听说了一个端口(我再也找不到了)。

        2
  •  3
  •   LukáÅ¡ Lalinský    15 年前

    那你就不能用了 .communicate() .您可以轮询流,使用 select 或者其他一些可以让您监听fd更改的方法(例如,gtk和qt都有相应的工具)。

        3
  •  3
  •   k0pernikus    10 年前

    看一看 Doug Hellman's Python Module of the Week writeup about subprocess . 向下搜索直到看到“repeater.py”。

    在这里,您将找到一个如何向进程发送和接收输入/输出的示例。

        4
  •  1
  •   Casebash    15 年前

    这是我写的一个模块。确保使用-u参数避免缓冲问题:

    import os
    import pickle
    import subprocess
    from subprocess import PIPE
    import struct
    import builtins
    def call_thru_stream(stream,funcname,*args,**kwargs):
        """Used for calling a function through a stream and no return value is required. It is assumed
        the receiving program is in the state where it is expecting a function."""
        transmit_object(stream,(funcname,args,kwargs))
    
    
    def function_thru_stream(in_stream,out_stream,funcname,*args,**kwargs):
        """Used for calling a function through a stream where a return value is required. It is assumed
        the receiving program is in the state where it is expecting a function."""
        transmit_object(in_stream,(funcname,args,kwargs))
        return receive_object(out_stream)
    
    #--------------------- Object layer ------------------------------------------------------------
    
    def transmit_object(stream,obj):
        """Transmits an object through a binary stream"""
        data=pickle.dumps(obj,2)#Uses pickle version 2 for compatibility with 2x
        transmit_atom(stream,data)
    
    
    def receive_object(stream):
        """Receive an object through a binary stream"""
        atom=receive_atom(stream)
        return pickle.loads(atom)
    
    #--------------------- Atom layer --------------------------------------------------------------
    def transmit_atom(stream, atom_bytes):
        """Used for transmitting a some bytes which should be treated as an atom through
        a stream. An integer indicating the size of the atom is appended to the start."""
        header=struct.pack("=L",len(atom_bytes))
        stream.write(header)
        stream.write(atom_bytes)
        stream.flush()
    
    
    def receive_atom(stream):
        """Read an atom from a binary stream and return the bytes."""
        input_len=stream.read(4)
        l=struct.unpack("=L",input_len)[0]
        return stream.read(l)   
    
    推荐文章