简体   繁体   English

使用subprocess.Popen调用python脚本并刷新数据

[英]Calling python script with subprocess.Popen and flushing the data

Ok so i've seen dozen of threads like that , but none of them gives a complete answer and everything i tried so far foes not work for me. 好的,所以我已经看到了十几个这样的线程,但是没有一个给出了完整的答案,我到目前为止所做的一切都不适合我。

1) Script that constantly outputs some data and flusheshs it: 1)不断输出一些数据并刷新它的脚本:

import time
import sys

if __name__ == '__main__':
    for i in range(5):
        print i,
        sys.stdout.flush()
        time.sleep(1)

2) Script that calls first script with Popen and should be printing numbers one by one but for some reason does not, and prints them alltogether at once : 2)用Popen调用第一个脚本的脚本,应该逐个打印数字但由于某种原因没有,并且一次打印它们:

import sys
import subprocess

if __name__ == '__main__':
    process = subprocess.Popen(['python', 'flush.py'], stdout = subprocess.PIPE )
    for line in iter(process.stdout.readline, ''):
        print line,
        sys.stdout.flush()

First thing i am a little bit confused is in the first script is that if you remove the flush it returns output in one line alltogether O_O... I am pretty sure it is because of time.sleep but still kind of expected it return like a standart output constantly returning values 0,1,2,3,4 but not all together, ofcourse flush resolves it , but just strange, at least for me ... 我有点困惑的第一件事就是在第一个脚本中,如果你删除了flush它会在一行中返回输出O_O ...我很确定这是因为time.sleep但仍然有点预期它会像一个标准输出不断返回值0,1,2,3,4但不是全部在一起,当然冲洗解决它,但只是奇怪,至少对我来说......

The main problem: Is that second script does not return number one by one , but returns all in one output at once..... What i need is to see numbers popping one by one... 主要问题:第二个脚本是不是一个一个地返回数字,而是一次性返回一个输出.....我需要的是看到数字逐个弹出...

I read somewhere that it does not return EOF which Popen waits to close the pipe , thats why it runs like to the end ..... 我读到某个地方,它没有返回EOF,Popen等待关闭管道,这就是为什么它运行到最后......

So what do i do or try next ? 那我该怎么办或接下来尝试一下呢? Thanks in advance. 提前致谢。

As @Warren Weckesser's comment says, your problem is unrelated to buffering issues . 正如@Warren Weckesser的评论所说,你的问题与缓冲问题无关。

.readline() in the parent process won't return until it reads a newline or reaches EOF. 父进程中的.readline()在读取换行符或达到EOF之前不会返回。 Your child process doesn't print any newlines at all so your parent process doesn't print anything until the child process ends. 您的子进程根本不打印任何换行符,因此在子进程结束之前,父进程不会打印任何内容

The minimal fix is just to remove comma at the end of print i, in the child script. 最小修复只是在子脚本中删除print i,末尾的逗号。

This also works: 这也有效:

#!/usr/bin/env python
import sys
from subprocess import Popen, PIPE

p = Popen([sys.executable or 'python',
           '-u', # unbuffer stdout (or make it line-buffered on Python 3)
           '-c',
           """
import time

for i in range(5):
    print(i) # <-- no comma i.e., each number is on its own line
    time.sleep(1)
"""], stdout=PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print(int(line)**2)

Example: 例:

 $ python parent.py
 0
 1
 4
 9
 16

The numbers are printed every seconds without waiting for the child process to end. 数字每秒打印一次,无需等待子进程结束。

If you don't want to change the child script then you should use readline() that stops at whitespace instead of a newline character eg: 如果您不想更改子脚本,那么您应该使用在空格处停止的readline()而不是换行符,例如:

#!/usr/bin/env python
import sys
from subprocess import Popen, PIPE

p = Popen(['python2', 'child.py'], stdout=PIPE, bufsize=0)
for token in generate_tokens(p.stdout):
    print(int(token))

where generate_tokens() yields whitespace-separated tokens: 其中generate_tokens()产生以空格分隔的标记:

def generate_tokens(pipe):
    buf = []
    while True:
        b = pipe.read(1) # read one byte
        if not b: # EOF
            pipe.close()
            if buf:
                yield b''.join(buf)
            return
        elif not b.isspace(): # grow token
            buf.append(b)
        elif buf: # full token read
            yield b''.join(buf)
            buf = []

It also prints integers as soon as they are printed by the child. 它还会在孩子打印后立即打印整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM