Если у вас есть данный ключ, вы можете использовать метод higherKey(key)
и lowerKey(key)
, соответственно.
Есть также соответствующие xxxEntry()
варианты.
Прошло много времени с тех пор, как я последний раз работал с Python, но я думаю, что проблема заключается в операторе for line в proc.stdout
, который считывает весь вход перед итерацией по нему. Решением является использование readline()
вместо этого:
#filters output
import subprocess
proc = subprocess.Popen(['python','fake_utility.py'],stdout=subprocess.PIPE)
while True:
line = proc.stdout.readline()
if not line:
break
#the real code does filtering here
print "test:", line.rstrip()
Конечно, вам все равно придется иметь дело с буферизацией подпроцесса.
Примечание: согласно документации решение с итератором должно быть эквивалентно использованию readline()
, за исключением буфера для чтения вперед, но (или именно из-за этого) предложенное изменение дало мне другие результаты (Python 2.5 на Windows XP).
Функция, позволяющая выполнять итерации по stdout
и stderr
одновременно, в режиме реального времени, построчно
В случае, если вам нужно получить выходной поток для обоих stdout
и stderr
одновременно, вы можете использовать следующую функцию.
Функция использует очереди для объединения обоих каналов Popen в один итератор.
Здесь мы создаем функцию read_popen_pipes()
:
from queue import Queue, Empty
from concurrent.futures import ThreadPoolExecutor
def enqueue_output(file, queue):
for line in iter(file.readline, ''):
queue.put(line)
file.close()
def read_popen_pipes(p):
with ThreadPoolExecutor(2) as pool:
q_stdout, q_stderr = Queue(), Queue()
pool.submit(enqueue_output, p.stdout, q_stdout)
pool.submit(enqueue_output, p.stderr, q_stderr)
while True:
out_line = err_line = ''
try:
out_line = q_stdout.get_nowait()
err_line = q_stderr.get_nowait()
except Empty:
pass
yield (out_line, err_line)
if p.poll() is not None:
break
read_popen_pipes()
и используем:
import subprocess as sp
with sp.Popen(my_cmd, stdout=sp.PIPE, stderr=sp.PIPE, text=True) as p:
for out_line, err_line in read_popen_pipes(p):
# Do stuff with each line, e.g.:
print(out_line, end='')
print(err_line, end='')
return p.poll() # return status-code